summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
dbe11c2)
In order for a point-to-point netlink to correctly construct and
deliver ICMP, it needs to know which way the original packet was
going. So provide the ICMP generation code with this information, in
the form of the "sender" client.
No functional change.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
/* client indicates where the packet we're constructing a response to
comes from. NULL indicates the host. */
/* client indicates where the packet we're constructing a response to
comes from. NULL indicates the host. */
-static void netlink_icmp_simple(struct netlink *st, struct buffer_if *buf,
+static void netlink_icmp_simple(struct netlink *st,
+ struct netlink_client *origsender,
+ struct buffer_if *buf,
uint8_t type, uint8_t code,
union icmpinfofield info)
{
uint8_t type, uint8_t code,
union icmpinfofield info)
{
/* Fragment or send ICMP Fragmentation Needed */
static void netlink_maybe_fragment(struct netlink *st,
/* Fragment or send ICMP Fragmentation Needed */
static void netlink_maybe_fragment(struct netlink *st,
+ struct netlink_client *sender,
netlink_deliver_fn *deliver,
void *deliver_dst,
const char *delivery_name,
netlink_deliver_fn *deliver,
void *deliver_dst,
const char *delivery_name,
if (orig_frag&IPHDR_FRAG_DONT) {
union icmpinfofield info =
{ .fragneeded = { .unused = 0, .mtu = htons(mtu) } };
if (orig_frag&IPHDR_FRAG_DONT) {
union icmpinfofield info =
{ .fragneeded = { .unused = 0, .mtu = htons(mtu) } };
- netlink_icmp_simple(st,buf,
+ netlink_icmp_simple(st,sender,buf,
ICMP_TYPE_UNREACHABLE,
ICMP_CODE_FRAGMENTATION_REQUIRED,
info);
ICMP_TYPE_UNREACHABLE,
ICMP_CODE_FRAGMENTATION_REQUIRED,
info);
- netlink_maybe_fragment(st, client->deliver,client->dst,client->name,
+ netlink_maybe_fragment(st,NULL, client->deliver,client->dst,client->name,
client->mtu, source,dest,buf);
client->outcount++;
}
client->mtu, source,dest,buf);
client->outcount++;
}
/* Deliver a packet to the host; used after we have decided that that
* is what to do with it. */
static void netlink_host_deliver(struct netlink *st,
/* Deliver a packet to the host; used after we have decided that that
* is what to do with it. */
static void netlink_host_deliver(struct netlink *st,
+ struct netlink_client *sender,
uint32_t source, uint32_t dest,
struct buffer_if *buf)
{
uint32_t source, uint32_t dest,
struct buffer_if *buf)
{
- netlink_maybe_fragment(st, st->deliver_to_host,st->dst,"(host)",
+ netlink_maybe_fragment(st,sender, st->deliver_to_host,st->dst,"(host)",
st->mtu, source,dest,buf);
st->outcount++;
}
st->mtu, source,dest,buf);
st->outcount++;
}
/* The packet's not going down a tunnel. It might (ought to)
be for the host. */
if (ipset_contains_addr(st->networks,dest)) {
/* The packet's not going down a tunnel. It might (ought to)
be for the host. */
if (ipset_contains_addr(st->networks,dest)) {
- netlink_host_deliver(st,source,dest,buf);
+ netlink_host_deliver(st,sender,source,dest,buf);
BUF_ASSERT_FREE(buf);
} else {
string_t s,d;
BUF_ASSERT_FREE(buf);
} else {
string_t s,d;
Message(M_DEBUG,"%s: don't know where to deliver packet "
"(s=%s, d=%s)\n", st->name, s, d);
free(s); free(d);
Message(M_DEBUG,"%s: don't know where to deliver packet "
"(s=%s, d=%s)\n", st->name, s, d);
free(s); free(d);
- netlink_icmp_simple(st,buf,ICMP_TYPE_UNREACHABLE,
+ netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_UNREACHABLE, icmp_noinfo);
BUF_FREE(buf);
}
ICMP_CODE_NET_UNREACHABLE, icmp_noinfo);
BUF_FREE(buf);
}
st->name,s,d);
free(s); free(d);
st->name,s,d);
free(s); free(d);
- netlink_icmp_simple(st,buf,ICMP_TYPE_UNREACHABLE,
+ netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_PROHIBITED, icmp_noinfo);
BUF_FREE(buf);
} else {
ICMP_CODE_NET_PROHIBITED, icmp_noinfo);
BUF_FREE(buf);
} else {
BUF_ASSERT_FREE(buf);
} else {
/* Generate ICMP destination unreachable */
BUF_ASSERT_FREE(buf);
} else {
/* Generate ICMP destination unreachable */
- netlink_icmp_simple(st,buf,
+ netlink_icmp_simple(st,sender,buf,
ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_UNREACHABLE,
icmp_noinfo);
ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_UNREACHABLE,
icmp_noinfo);
/* Packet has already been checked */
if (iph->ttl<=1) {
/* Generate ICMP time exceeded */
/* Packet has already been checked */
if (iph->ttl<=1) {
/* Generate ICMP time exceeded */
- netlink_icmp_simple(st,buf,ICMP_TYPE_TIME_EXCEEDED,
+ netlink_icmp_simple(st,sender,buf,ICMP_TYPE_TIME_EXCEEDED,
ICMP_CODE_TTL_EXCEEDED,icmp_noinfo);
BUF_FREE(buf);
return;
ICMP_CODE_TTL_EXCEEDED,icmp_noinfo);
BUF_FREE(buf);
return;
Message(M_WARNING,"%s: unknown incoming ICMP\n",st->name);
} else {
/* Send ICMP protocol unreachable */
Message(M_WARNING,"%s: unknown incoming ICMP\n",st->name);
} else {
/* Send ICMP protocol unreachable */
- netlink_icmp_simple(st,buf,ICMP_TYPE_UNREACHABLE,
+ netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_PROTOCOL_UNREACHABLE,icmp_noinfo);
BUF_FREE(buf);
return;
ICMP_CODE_PROTOCOL_UNREACHABLE,icmp_noinfo);
BUF_FREE(buf);
return;
address validity and generate ICMP, etc. */
if (st->ptp) {
if (sender) {
address validity and generate ICMP, etc. */
if (st->ptp) {
if (sender) {
- netlink_host_deliver(st,source,dest,buf);
+ netlink_host_deliver(st,sender,source,dest,buf);
} else {
netlink_client_deliver(st,st->clients,source,dest,buf);
}
} else {
netlink_client_deliver(st,st->clients,source,dest,buf);
}