Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: shoot ipv6 icmp redirects #494

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading