Skip to content

Commit fa55a7d

Browse files
lunndavem330
authored andcommitted
seg6: export get_srh() for ICMP handling
An ICMP error message can contain in its message body part of an IPv6 packet which invoked the error. Such a packet might contain a segment router header. Export get_srh() so the ICMP code can make use of it. Since his changes the scope of the function from local to global, add the seg6_ prefix to keep the namespace clean. And move it into seg6.c so it is always available, not just when IPV6_SEG6_LWTUNNEL is enabled. Signed-off-by: Andrew Lunn <[email protected]> Reviewed-by: David Ahern <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e8fe9e8 commit fa55a7d

File tree

3 files changed

+32
-31
lines changed

3 files changed

+32
-31
lines changed

include/net/seg6.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ extern int seg6_local_init(void);
5858
extern void seg6_local_exit(void);
5959

6060
extern bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced);
61+
extern struct ipv6_sr_hdr *seg6_get_srh(struct sk_buff *skb, int flags);
6162
extern int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh,
6263
int proto);
6364
extern int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh);

net/ipv6/seg6.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,35 @@ bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced)
7575
return true;
7676
}
7777

78+
struct ipv6_sr_hdr *seg6_get_srh(struct sk_buff *skb, int flags)
79+
{
80+
struct ipv6_sr_hdr *srh;
81+
int len, srhoff = 0;
82+
83+
if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, &flags) < 0)
84+
return NULL;
85+
86+
if (!pskb_may_pull(skb, srhoff + sizeof(*srh)))
87+
return NULL;
88+
89+
srh = (struct ipv6_sr_hdr *)(skb->data + srhoff);
90+
91+
len = (srh->hdrlen + 1) << 3;
92+
93+
if (!pskb_may_pull(skb, srhoff + len))
94+
return NULL;
95+
96+
/* note that pskb_may_pull may change pointers in header;
97+
* for this reason it is necessary to reload them when needed.
98+
*/
99+
srh = (struct ipv6_sr_hdr *)(skb->data + srhoff);
100+
101+
if (!seg6_validate_srh(srh, len, true))
102+
return NULL;
103+
104+
return srh;
105+
}
106+
78107
static struct genl_family seg6_genl_family;
79108

80109
static const struct nla_policy seg6_genl_policy[SEG6_ATTR_MAX + 1] = {

net/ipv6/seg6_local.c

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -150,40 +150,11 @@ static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt)
150150
return (struct seg6_local_lwt *)lwt->data;
151151
}
152152

153-
static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb, int flags)
154-
{
155-
struct ipv6_sr_hdr *srh;
156-
int len, srhoff = 0;
157-
158-
if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, &flags) < 0)
159-
return NULL;
160-
161-
if (!pskb_may_pull(skb, srhoff + sizeof(*srh)))
162-
return NULL;
163-
164-
srh = (struct ipv6_sr_hdr *)(skb->data + srhoff);
165-
166-
len = (srh->hdrlen + 1) << 3;
167-
168-
if (!pskb_may_pull(skb, srhoff + len))
169-
return NULL;
170-
171-
/* note that pskb_may_pull may change pointers in header;
172-
* for this reason it is necessary to reload them when needed.
173-
*/
174-
srh = (struct ipv6_sr_hdr *)(skb->data + srhoff);
175-
176-
if (!seg6_validate_srh(srh, len, true))
177-
return NULL;
178-
179-
return srh;
180-
}
181-
182153
static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb)
183154
{
184155
struct ipv6_sr_hdr *srh;
185156

186-
srh = get_srh(skb, IP6_FH_F_SKIP_RH);
157+
srh = seg6_get_srh(skb, IP6_FH_F_SKIP_RH);
187158
if (!srh)
188159
return NULL;
189160

@@ -200,7 +171,7 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)
200171
struct ipv6_sr_hdr *srh;
201172
unsigned int off = 0;
202173

203-
srh = get_srh(skb, 0);
174+
srh = seg6_get_srh(skb, 0);
204175
if (srh && srh->segments_left > 0)
205176
return false;
206177

0 commit comments

Comments
 (0)