Commit 1d5d0a07 authored by David S. Miller's avatar David S. Miller

Merge branch 'seg6-next'

Julien Massonneau says:

====================
SRv6: SRH processing improvements

Add support for IPv4 decapsulation in ipv6_srh_rcv() and
ignore routing header with segments left equal to 0 for
seg6local actions that doesn't perfom decapsulation.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6c609521 fbbc5bc2
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
*/ */
#define NEXTHDR_HOP 0 /* Hop-by-hop option header. */ #define NEXTHDR_HOP 0 /* Hop-by-hop option header. */
#define NEXTHDR_IPV4 4 /* IPv4 in IPv6 */
#define NEXTHDR_TCP 6 /* TCP segment. */ #define NEXTHDR_TCP 6 /* TCP segment. */
#define NEXTHDR_UDP 17 /* UDP message. */ #define NEXTHDR_UDP 17 /* UDP message. */
#define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */ #define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */
......
...@@ -381,7 +381,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb) ...@@ -381,7 +381,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
looped_back: looped_back:
if (hdr->segments_left == 0) { if (hdr->segments_left == 0) {
if (hdr->nexthdr == NEXTHDR_IPV6) { if (hdr->nexthdr == NEXTHDR_IPV6 || hdr->nexthdr == NEXTHDR_IPV4) {
int offset = (hdr->hdrlen + 1) << 3; int offset = (hdr->hdrlen + 1) << 3;
skb_postpull_rcsum(skb, skb_network_header(skb), skb_postpull_rcsum(skb, skb_network_header(skb),
...@@ -397,7 +397,8 @@ static int ipv6_srh_rcv(struct sk_buff *skb) ...@@ -397,7 +397,8 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
skb_reset_network_header(skb); skb_reset_network_header(skb);
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
skb->encapsulation = 0; skb->encapsulation = 0;
if (hdr->nexthdr == NEXTHDR_IPV4)
skb->protocol = htons(ETH_P_IP);
__skb_tunnel_rx(skb, skb->dev, net); __skb_tunnel_rx(skb, skb->dev, net);
netif_rx(skb); netif_rx(skb);
......
...@@ -119,12 +119,12 @@ static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt) ...@@ -119,12 +119,12 @@ static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt)
return (struct seg6_local_lwt *)lwt->data; return (struct seg6_local_lwt *)lwt->data;
} }
static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb) static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb, int flags)
{ {
struct ipv6_sr_hdr *srh; struct ipv6_sr_hdr *srh;
int len, srhoff = 0; int len, srhoff = 0;
if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, NULL) < 0) if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, &flags) < 0)
return NULL; return NULL;
if (!pskb_may_pull(skb, srhoff + sizeof(*srh))) if (!pskb_may_pull(skb, srhoff + sizeof(*srh)))
...@@ -152,13 +152,10 @@ static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb) ...@@ -152,13 +152,10 @@ static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb)
{ {
struct ipv6_sr_hdr *srh; struct ipv6_sr_hdr *srh;
srh = get_srh(skb); srh = get_srh(skb, IP6_FH_F_SKIP_RH);
if (!srh) if (!srh)
return NULL; return NULL;
if (srh->segments_left == 0)
return NULL;
#ifdef CONFIG_IPV6_SEG6_HMAC #ifdef CONFIG_IPV6_SEG6_HMAC
if (!seg6_hmac_validate_skb(skb)) if (!seg6_hmac_validate_skb(skb))
return NULL; return NULL;
...@@ -172,7 +169,7 @@ static bool decap_and_validate(struct sk_buff *skb, int proto) ...@@ -172,7 +169,7 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)
struct ipv6_sr_hdr *srh; struct ipv6_sr_hdr *srh;
unsigned int off = 0; unsigned int off = 0;
srh = get_srh(skb); srh = get_srh(skb, 0);
if (srh && srh->segments_left > 0) if (srh && srh->segments_left > 0)
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment