With this commit unicast_safe packets generated by a node in redundant bonding mode will be processed on reception. It is being transformed back to a normal unicast packet if the packet is for the node itself or if redundant bonding mode is deactivated on this node. Otherwise it is being passed on as is to the routing functions.
Signed-off-by: Linus Lüssing linus.luessing@ascom.ch --- hard-interface.c | 5 ++++ routing.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++--- routing.h | 1 + 3 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/batman-adv/hard-interface.c b/batman-adv/hard-interface.c index 52d32f2..fa12a4e 100644 --- a/batman-adv/hard-interface.c +++ b/batman-adv/hard-interface.c @@ -623,6 +623,11 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, ret = recv_ucast_frag_packet(skb, batman_if); break;
+ /* fragmented unicast packet */ + case BAT_UNICAST_SAFE: + ret = recv_ucast_safe_packet(skb, batman_if); + break; + /* broadcast packet */ case BAT_BCAST: ret = recv_bcast_packet(skb, batman_if); diff --git a/batman-adv/routing.c b/batman-adv/routing.c index 0797ab5..4aa7fb5 100644 --- a/batman-adv/routing.c +++ b/batman-adv/routing.c @@ -1017,6 +1017,29 @@ out: return ret; }
+static void unicast_safe_to_unicast(struct sk_buff *skb) +{ + struct unicast_packet_safe unicast_packet_safe; + struct unicast_packet *unicast_packet; + + unicast_packet_safe = *((struct unicast_packet_safe *)skb->data); + unicast_packet = (struct unicast_packet *) skb_pull(skb, + sizeof(struct unicast_packet_safe) - + sizeof(struct unicast_packet)); + + unicast_packet->header = unicast_packet_safe.header; + unicast_packet->header.packet_type = BAT_UNICAST; + memcpy(unicast_packet->dest, unicast_packet_safe.dest, ETH_ALEN); +} + +static void set_unicast_safe_options(struct bat_priv *bat_priv, + struct unicast_packet_safe *unicast_packet) +{ + memcpy(unicast_packet->orig, bat_priv->primary_if->net_dev->dev_addr, + ETH_ALEN); + unicast_packet->seqno = htonl(atomic_inc_return(&bat_priv->dup_seqno)); +} + static int unicast_to_unicast_safe(struct sk_buff *skb, struct bat_priv *bat_priv) { @@ -1032,10 +1055,7 @@ static int unicast_to_unicast_safe(struct sk_buff *skb, unicast_packet_safe->header = unicast_packet.header; memcpy(unicast_packet_safe->dest, unicast_packet.dest, ETH_ALEN); unicast_packet_safe->header.packet_type = BAT_UNICAST_SAFE; - memcpy(unicast_packet_safe->orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - unicast_packet_safe->seqno = - htonl(atomic_inc_return(&bat_priv->dup_seqno)); + set_unicast_safe_options(bat_priv, unicast_packet_safe);
return 0; } @@ -1383,6 +1403,38 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) return route_unicast_packet(bonding_mode, skb, recv_if, orig_node); }
+int recv_ucast_safe_packet(struct sk_buff *skb, struct batman_if *recv_if) +{ + struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); + struct unicast_packet_safe *unicast_packet; + struct orig_node *orig_node; + int hdr_size = sizeof(struct unicast_packet); + int bonding_mode; + + if (check_unicast_packet(skb, hdr_size) < 0) + return NET_RX_DROP; + + unicast_packet = (struct unicast_packet_safe *)skb->data; + + /* packet for me */ + if (is_my_mac(unicast_packet->dest)) { + unicast_safe_to_unicast(skb); + + interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); + return NET_RX_SUCCESS; + } + + bonding_mode = atomic_read(&bat_priv->bonding) << + atomic_read(&bat_priv->red_bonding); + + if (bonding_mode != REDUNDANT_BONDING) + unicast_safe_to_unicast(skb); + else + set_unicast_safe_options(bat_priv, unicast_packet); + + orig_node = hash_find_orig(bat_priv, unicast_packet->dest); + return route_unicast_packet(bonding_mode, skb, recv_if, orig_node); +}
int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) { diff --git a/batman-adv/routing.h b/batman-adv/routing.h index 01fab8d..146b290 100644 --- a/batman-adv/routing.h +++ b/batman-adv/routing.h @@ -36,6 +36,7 @@ int route_unicast_packet(int bonding_mode, struct sk_buff *skb, int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if); +int recv_ucast_safe_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if);