From: David Lebrun <david.lebrun@uclouvain.be>
To: <netdev@vger.kernel.org>
Cc: David Lebrun <david.lebrun@uclouvain.be>
Subject: [PATCH net-next v2 5/5] ipv6: sr: implement additional seg6local actions
Date: Fri, 25 Aug 2017 09:58:17 +0200 [thread overview]
Message-ID: <20170825075817.5239-1-david.lebrun@uclouvain.be> (raw)
In-Reply-To: <20170825075648.5061-1-david.lebrun@uclouvain.be>
This patch implements the following seg6local actions.
- SEG6_LOCAL_ACTION_END_T: regular SRH processing and forward to the
next-hop looked up in the specified routing table.
- SEG6_LOCAL_ACTION_END_DX2: decapsulate an L2 frame and forward it to
the specified network interface.
- SEG6_LOCAL_ACTION_END_DX4: decapsulate an IPv4 packet and forward it,
possibly to the specified next-hop.
- SEG6_LOCAL_ACTION_END_DT6: decapsulate an IPv6 packet and forward it
to the next-hop looked up in the specified routing table.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/seg6_local.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 147 insertions(+)
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 26db4d3e..9c1a885 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -30,6 +30,7 @@
#ifdef CONFIG_IPV6_SEG6_HMAC
#include <net/seg6_hmac.h>
#endif
+#include <linux/etherdevice.h>
struct seg6_local_lwt;
@@ -226,6 +227,82 @@ static int input_action_end_x(struct sk_buff *skb, struct seg6_local_lwt *slwt)
return -EINVAL;
}
+static int input_action_end_t(struct sk_buff *skb, struct seg6_local_lwt *slwt)
+{
+ struct ipv6_sr_hdr *srh;
+
+ srh = get_and_validate_srh(skb);
+ if (!srh)
+ goto drop;
+
+ advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
+
+ lookup_nexthop(skb, NULL, slwt->table);
+
+ return dst_input(skb);
+
+drop:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+/* decapsulate and forward inner L2 frame on specified interface */
+static int input_action_end_dx2(struct sk_buff *skb,
+ struct seg6_local_lwt *slwt)
+{
+ struct net *net = dev_net(skb->dev);
+ struct net_device *odev;
+ struct ethhdr *eth;
+
+ if (!decap_and_validate(skb, NEXTHDR_NONE))
+ goto drop;
+
+ if (!pskb_may_pull(skb, ETH_HLEN))
+ goto drop;
+
+ skb_reset_mac_header(skb);
+ eth = (struct ethhdr *)skb->data;
+
+ /* To determine the frame's protocol, we assume it is 802.3. This avoids
+ * a call to eth_type_trans(), which is not really relevant for our
+ * use case.
+ */
+ if (!eth_proto_is_802_3(eth->h_proto))
+ goto drop;
+
+ odev = dev_get_by_index_rcu(net, slwt->oif);
+ if (!odev)
+ goto drop;
+
+ /* As we accept Ethernet frames, make sure the egress device is of
+ * the correct type.
+ */
+ if (odev->type != ARPHRD_ETHER)
+ goto drop;
+
+ if (!(odev->flags & IFF_UP) || !netif_carrier_ok(odev))
+ goto drop;
+
+ skb_orphan(skb);
+
+ if (skb_warn_if_lro(skb))
+ goto drop;
+
+ skb_forward_csum(skb);
+
+ if (skb->len - ETH_HLEN > odev->mtu)
+ goto drop;
+
+ skb->dev = odev;
+ skb->protocol = eth->h_proto;
+
+ return dev_queue_xmit(skb);
+
+drop:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
/* decapsulate and forward to specified nexthop */
static int input_action_end_dx6(struct sk_buff *skb,
struct seg6_local_lwt *slwt)
@@ -260,6 +337,56 @@ static int input_action_end_dx6(struct sk_buff *skb,
return -EINVAL;
}
+static int input_action_end_dx4(struct sk_buff *skb,
+ struct seg6_local_lwt *slwt)
+{
+ struct iphdr *iph;
+ __be32 nhaddr;
+ int err;
+
+ if (!decap_and_validate(skb, IPPROTO_IPIP))
+ goto drop;
+
+ if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ goto drop;
+
+ skb->protocol = htons(ETH_P_IP);
+
+ iph = ip_hdr(skb);
+
+ nhaddr = slwt->nh4.s_addr ?: iph->daddr;
+
+ skb_dst_drop(skb);
+
+ err = ip_route_input(skb, nhaddr, iph->saddr, 0, skb->dev);
+ if (err)
+ goto drop;
+
+ return dst_input(skb);
+
+drop:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
+static int input_action_end_dt6(struct sk_buff *skb,
+ struct seg6_local_lwt *slwt)
+{
+ if (!decap_and_validate(skb, IPPROTO_IPV6))
+ goto drop;
+
+ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+ goto drop;
+
+ lookup_nexthop(skb, NULL, slwt->table);
+
+ return dst_input(skb);
+
+drop:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
/* push an SRH on top of the current one */
static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
{
@@ -330,11 +457,31 @@ static struct seg6_action_desc seg6_action_table[] = {
.input = input_action_end_x,
},
{
+ .action = SEG6_LOCAL_ACTION_END_T,
+ .attrs = (1 << SEG6_LOCAL_TABLE),
+ .input = input_action_end_t,
+ },
+ {
+ .action = SEG6_LOCAL_ACTION_END_DX2,
+ .attrs = (1 << SEG6_LOCAL_OIF),
+ .input = input_action_end_dx2,
+ },
+ {
.action = SEG6_LOCAL_ACTION_END_DX6,
.attrs = (1 << SEG6_LOCAL_NH6),
.input = input_action_end_dx6,
},
{
+ .action = SEG6_LOCAL_ACTION_END_DX4,
+ .attrs = (1 << SEG6_LOCAL_NH4),
+ .input = input_action_end_dx4,
+ },
+ {
+ .action = SEG6_LOCAL_ACTION_END_DT6,
+ .attrs = (1 << SEG6_LOCAL_TABLE),
+ .input = input_action_end_dt6,
+ },
+ {
.action = SEG6_LOCAL_ACTION_END_B6,
.attrs = (1 << SEG6_LOCAL_SRH),
.input = input_action_end_b6,
--
2.10.2
next prev parent reply other threads:[~2017-08-25 7:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-25 7:56 [PATCH net-next v2 0/5] net: updates for IPv6 Segment Routing David Lebrun
2017-08-25 7:56 ` [PATCH net-next v2 1/5] ipv6: sr: add support for ip4ip6 encapsulation David Lebrun
2017-08-25 7:56 ` [PATCH net-next v2 2/5] ipv6: sr: add support for encapsulation of L2 frames David Lebrun
2017-08-25 7:56 ` [PATCH net-next v2 3/5] ipv6: sr: enforce IPv6 packets for seg6local lwt David Lebrun
2017-08-25 7:56 ` [PATCH net-next v2 4/5] ipv6: sr: add helper functions for seg6local David Lebrun
2017-08-25 7:58 ` David Lebrun [this message]
2017-08-26 0:10 ` [PATCH net-next v2 0/5] net: updates for IPv6 Segment Routing David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170825075817.5239-1-david.lebrun@uclouvain.be \
--to=david.lebrun@uclouvain.be \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).