Skip to content

Commit

Permalink
fix: shoot ipv6 icmp redirects (#494)
Browse files Browse the repository at this point in the history
  • Loading branch information
mzz2017 authored Apr 8, 2024
1 parent 3a83d98 commit 7defd23
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
32 changes: 32 additions & 0 deletions control/control_plane_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,38 @@ func (c *controlPlaneCore) _bindLan(ifname string) error {
}
return nil
})

filterEgress := &netlink.BpfFilter{
FilterAttrs: netlink.FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: netlink.HANDLE_MIN_EGRESS,
Handle: netlink.MakeHandle(0x2023, 0b010+uint16(c.flip)),
Protocol: unix.ETH_P_ALL,
// Priority should be front of WAN's
Priority: 1,
},
Fd: c.bpf.bpfPrograms.TproxyLanEgress.FD(),
Name: consts.AppName + "_lan_egress",
DirectAction: true,
}
// Remove and add.
_ = netlink.FilterDel(filterEgress)
if !c.isReload {
// Clean up thoroughly.
filterEgressFlipped := deepcopy.Copy(filterEgress).(*netlink.BpfFilter)
filterEgressFlipped.FilterAttrs.Handle ^= 1
_ = netlink.FilterDel(filterEgressFlipped)
}
if err := netlink.FilterAdd(filterEgress); err != nil {
return fmt.Errorf("cannot attach ebpf object to filter egress: %w", err)
}
c.deferFuncs = append(c.deferFuncs, func() error {
if err := netlink.FilterDel(filterEgress); err != nil {
return fmt.Errorf("FilterDel(%v:%v): %w", ifname, filterEgress.Name, err)
}
return nil
})

return nil
}

Expand Down
33 changes: 33 additions & 0 deletions control/kern/tproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@

#define ESOCKTNOSUPPORT 94 /* Socket type not supported */

#define NDP_REDIRECT 137

enum { BPF_F_CURRENT_NETNS = -1 };

enum {
Expand Down Expand Up @@ -961,6 +963,37 @@ static __always_inline void prep_redirect_to_control_plane(
skb->cb[1] = l4proto;
}

SEC("tc/egress")
int tproxy_lan_egress(struct __sk_buff *skb)
{
if (skb->ingress_ifindex != NOWHERE_IFINDEX)
return TC_ACT_PIPE;

struct ethhdr ethh;
struct iphdr iph;
struct ipv6hdr ipv6h;
struct icmp6hdr icmp6h;
struct tcphdr tcph;
struct udphdr udph;
__u8 ihl;
__u8 l4proto;
__u32 link_h_len;

if (get_link_h_len(skb->ifindex, &link_h_len))
return TC_ACT_OK;
int ret = parse_transport(skb, link_h_len, &ethh, &iph, &ipv6h, &icmp6h,
&tcph, &udph, &ihl, &l4proto);
if (ret) {
bpf_printk("parse_transport: %d", ret);
return TC_ACT_OK;
}
if (l4proto == IPPROTO_ICMPV6 && icmp6h.icmp6_type == NDP_REDIRECT) {
// REDIRECT (NDP)
return TC_ACT_SHOT;
}
return TC_ACT_PIPE;
}

SEC("tc/ingress")
int tproxy_lan_ingress(struct __sk_buff *skb)
{
Expand Down

0 comments on commit 7defd23

Please sign in to comment.