Skip to content

Commit fd1fef0

Browse files
skorpion17davem330
authored andcommitted
seg6: allow local packet processing for SRv6 End.DT6 behavior
End.DT6 behavior makes use of seg6_lookup_nexthop() function which drops all packets that are destined to be locally processed. However, DT* should be able to deliver decapsulated packets that are destined to local addresses. Function seg6_lookup_nexthop() is also used by DX6, so in order to maintain compatibility I created another routing helper function which is called seg6_lookup_any_nexthop(). This function is able to take into account both packets that have to be processed locally and the ones that are destined to be forwarded directly to another machine. Hence, seg6_lookup_any_nexthop() is used in DT6 rather than seg6_lookup_nexthop() to allow local delivery. Signed-off-by: Andrea Mayer <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d1746d1 commit fd1fef0

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

net/ipv6/seg6_local.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,17 @@ static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
149149
*daddr = *addr;
150150
}
151151

152-
int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
153-
u32 tbl_id)
152+
static int
153+
seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
154+
u32 tbl_id, bool local_delivery)
154155
{
155156
struct net *net = dev_net(skb->dev);
156157
struct ipv6hdr *hdr = ipv6_hdr(skb);
157158
int flags = RT6_LOOKUP_F_HAS_SADDR;
158159
struct dst_entry *dst = NULL;
159160
struct rt6_info *rt;
160161
struct flowi6 fl6;
162+
int dev_flags = 0;
161163

162164
fl6.flowi6_iif = skb->dev->ifindex;
163165
fl6.daddr = nhaddr ? *nhaddr : hdr->daddr;
@@ -182,7 +184,13 @@ int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
182184
dst = &rt->dst;
183185
}
184186

185-
if (dst && dst->dev->flags & IFF_LOOPBACK && !dst->error) {
187+
/* we want to discard traffic destined for local packet processing,
188+
* if @local_delivery is set to false.
189+
*/
190+
if (!local_delivery)
191+
dev_flags |= IFF_LOOPBACK;
192+
193+
if (dst && (dst->dev->flags & dev_flags) && !dst->error) {
186194
dst_release(dst);
187195
dst = NULL;
188196
}
@@ -199,6 +207,12 @@ int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
199207
return dst->error;
200208
}
201209

210+
int seg6_lookup_nexthop(struct sk_buff *skb,
211+
struct in6_addr *nhaddr, u32 tbl_id)
212+
{
213+
return seg6_lookup_any_nexthop(skb, nhaddr, tbl_id, false);
214+
}
215+
202216
/* regular endpoint function */
203217
static int input_action_end(struct sk_buff *skb, struct seg6_local_lwt *slwt)
204218
{
@@ -396,7 +410,7 @@ static int input_action_end_dt6(struct sk_buff *skb,
396410

397411
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
398412

399-
seg6_lookup_nexthop(skb, NULL, slwt->table);
413+
seg6_lookup_any_nexthop(skb, NULL, slwt->table, true);
400414

401415
return dst_input(skb);
402416

0 commit comments

Comments
 (0)