Fix DecrementTTL option for packets destined to the local node.
Signed-off-by: Vittorio Gambaletta <openwrt@vittgam.net> # Conflicts: # src/route.c
This commit is contained in:
parent
17e54ea0be
commit
496f775568
1 changed files with 34 additions and 8 deletions
42
src/route.c
42
src/route.c
|
@ -55,6 +55,8 @@ static const size_t icmp6_size = sizeof(struct icmp6_hdr);
|
||||||
static const size_t ns_size = sizeof(struct nd_neighbor_solicit);
|
static const size_t ns_size = sizeof(struct nd_neighbor_solicit);
|
||||||
static const size_t opt_size = sizeof(struct nd_opt_hdr);
|
static const size_t opt_size = sizeof(struct nd_opt_hdr);
|
||||||
|
|
||||||
|
static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet);
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
@ -250,6 +252,14 @@ static void learn_mac(mac_t *address) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void broadcast_packet_helper(node_t *source, vpn_packet_t *packet) {
|
||||||
|
if(decrement_ttl && source != myself)
|
||||||
|
if(!do_decrement_ttl(source, packet))
|
||||||
|
return;
|
||||||
|
|
||||||
|
broadcast_packet(source, packet);
|
||||||
|
}
|
||||||
|
|
||||||
/* RFC 792 */
|
/* RFC 792 */
|
||||||
|
|
||||||
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
|
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
|
||||||
|
@ -419,7 +429,7 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!subnet->owner) {
|
if (!subnet->owner) {
|
||||||
broadcast_packet(source, packet);
|
broadcast_packet_helper(source, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,6 +444,10 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) {
|
||||||
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
||||||
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
|
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
|
||||||
|
|
||||||
|
if(decrement_ttl && source != myself && subnet->owner != myself)
|
||||||
|
if(!do_decrement_ttl(source, packet))
|
||||||
|
return;
|
||||||
|
|
||||||
if(priorityinheritance)
|
if(priorityinheritance)
|
||||||
packet->priority = DATA(packet)[15];
|
packet->priority = DATA(packet)[15];
|
||||||
|
|
||||||
|
@ -600,7 +614,7 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!subnet->owner) {
|
if (!subnet->owner) {
|
||||||
broadcast_packet(source, packet);
|
broadcast_packet_helper(source, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,6 +629,10 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) {
|
||||||
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
||||||
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
|
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
|
||||||
|
|
||||||
|
if(decrement_ttl && source != myself && subnet->owner != myself)
|
||||||
|
if(!do_decrement_ttl(source, packet))
|
||||||
|
return;
|
||||||
|
|
||||||
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
|
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
|
||||||
|
|
||||||
if(via == source) {
|
if(via == source) {
|
||||||
|
@ -731,6 +749,10 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) {
|
||||||
if(subnet->owner == myself)
|
if(subnet->owner == myself)
|
||||||
return; /* silently ignore */
|
return; /* silently ignore */
|
||||||
|
|
||||||
|
if(decrement_ttl)
|
||||||
|
if(!do_decrement_ttl(source, packet))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Create neighbor advertation reply */
|
/* Create neighbor advertation reply */
|
||||||
|
|
||||||
memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */
|
memcpy(DATA(packet), DATA(packet) + ETH_ALEN, ETH_ALEN); /* copy destination address */
|
||||||
|
@ -826,6 +848,10 @@ static void route_arp(node_t *source, vpn_packet_t *packet) {
|
||||||
if(subnet->owner == myself)
|
if(subnet->owner == myself)
|
||||||
return; /* silently ignore */
|
return; /* silently ignore */
|
||||||
|
|
||||||
|
if(decrement_ttl)
|
||||||
|
if(!do_decrement_ttl(source, packet))
|
||||||
|
return;
|
||||||
|
|
||||||
memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */
|
memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */
|
||||||
memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */
|
memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */
|
||||||
memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */
|
memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */
|
||||||
|
@ -860,7 +886,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
|
||||||
subnet = lookup_subnet_mac(NULL, &dest);
|
subnet = lookup_subnet_mac(NULL, &dest);
|
||||||
|
|
||||||
if(!subnet || !subnet->owner) {
|
if(!subnet || !subnet->owner) {
|
||||||
broadcast_packet(source, packet);
|
broadcast_packet_helper(source, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,6 +898,10 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
|
||||||
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(decrement_ttl && source != myself && subnet->owner != myself)
|
||||||
|
if(!do_decrement_ttl(source, packet))
|
||||||
|
return;
|
||||||
|
|
||||||
uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13];
|
uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13];
|
||||||
|
|
||||||
if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size)
|
if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size)
|
||||||
|
@ -994,10 +1024,6 @@ void route(node_t *source, vpn_packet_t *packet) {
|
||||||
if(!checklength(source, packet, ether_size))
|
if(!checklength(source, packet, ether_size))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(decrement_ttl && source != myself)
|
|
||||||
if(!do_decrement_ttl(source, packet))
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13];
|
uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13];
|
||||||
|
|
||||||
switch (routing_mode) {
|
switch (routing_mode) {
|
||||||
|
@ -1026,7 +1052,7 @@ void route(node_t *source, vpn_packet_t *packet) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RMODE_HUB:
|
case RMODE_HUB:
|
||||||
broadcast_packet(source, packet);
|
broadcast_packet_helper(source, packet);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue