[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1441122196-11662-19-git-send-email-ahmed@gandi.net>
Date: Tue, 1 Sep 2015 17:43:13 +0200
From: Ahmed Amamou <ahmed@...di.net>
To: netdev@...r.kernel.org
Cc: William Dauchy <william@...di.net>, Ahmed Amamou <ahmed@...di.net>,
Kamel Haddadou <kamel@...di.net>,
François Cachereul <f.cachereul@...halink.fr>
Subject: [PATCH RFC v2 18/21] net: rbridge: add rbr_fwd
add rbridge forward function
packets arriving to rbr_fwd should be already encapsulated and correct
egress
and ingress nickname should be already assigned
rbr_fwd function will assign correct source and destination outer MAC
addresses
according to which port will send the frame and next hop to reach
the engress nickname
Nexthope to reach the egress will be found in node database
Signed-off-by: Ahmed Amamou <ahmed@...di.net>
Signed-off-by: Kamel Haddadou <kamel@...di.net>
Signed-off-by: William Dauchy <william@...di.net>
Signed-off-by: François Cachereul <f.cachereul@...halink.fr>
---
net/bridge/rbr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/net/bridge/rbr.c b/net/bridge/rbr.c
index c04c05a..ab71e6b 100644
--- a/net/bridge/rbr.c
+++ b/net/bridge/rbr.c
@@ -172,6 +172,48 @@ static bool add_header(struct sk_buff *skb, uint16_t ingressnick,
return 0;
}
+static void rbr_fwd(struct net_bridge_port *p, struct sk_buff *skb,
+ u16 adj_nick, u16 vid)
+{
+ struct rbr_node *adj;
+ struct trill_hdr *trh;
+ struct ethhdr *outerethhdr;
+ struct net *net = dev_net(p->dev);
+ struct net_device *outdev;
+ struct net_bridge_port *outp;
+
+ adj = rbr_find_node(p->br->rbr, adj_nick);
+ if (unlikely(!adj || !adj->rbr_ni)) {
+ pr_warn_ratelimited("rbr_fwd: unable to find adjacent RBridge\n");
+ goto dest_fwd_fail;
+ }
+ outdev = dev_get_by_index_rcu(net, adj->rbr_ni->linkid);
+ if (!outdev) {
+ pr_warn_ratelimited("rbr_fwd: cannot find source port device for forwrding\n");
+ goto dest_fwd_fail;
+ }
+
+ trh = (struct trill_hdr *)skb->data;
+ trillhdr_dec_hopcount(trh);
+ outerethhdr = eth_hdr(skb);
+
+ /* change outer ether header */
+ /* bridge becomes the source_port address in outeretherhdr */
+ outp = br_port_get_rcu(outdev);
+ ether_addr_copy(outerethhdr->h_source, outp->dev->dev_addr);
+ /* dist port becomes dest address in outeretherhdr */
+ ether_addr_copy(outerethhdr->h_dest, adj->rbr_ni->adjsnpa);
+ rbr_node_put(adj);
+ skb->dev = p->br->dev;
+ br_forward(outp, skb, NULL);
+ return;
+
+dest_fwd_fail:
+ if (likely(p && p->br))
+ p->br->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+}
+
static void rbr_encaps(struct sk_buff *skb, u16 egressnick, u16 vid)
{
u16 local_nick;
@@ -234,7 +276,7 @@ static void rbr_encaps(struct sk_buff *skb, u16 egressnick, u16 vid)
} else {
if (unlikely(add_header(skb, local_nick, egressnick, 0)))
goto encaps_drop;
- /* TODO simple forwarding */
+ rbr_fwd(p, skb, egressnick, vid);
}
return;
encaps_drop:
@@ -373,7 +415,7 @@ static void rbr_recv(struct sk_buff *skb, u16 vid)
} else if (likely(trill_get_hopcount(trill_flags))) {
br_fdb_update(p->br, p, eth_hdr(skb)->h_source,
vid, false);
- /* TODO simple forwarding */
+ rbr_fwd(p, skb, trh->th_egressnick, vid);
} else {
pr_warn_ratelimited("rbr_recv: hop count limit reached\n");
goto recv_drop;
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists