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

vrrp: Duplicate/drop MLDv1 listener reports on VMACs #2454

Merged
merged 1 commit into from
Jul 24, 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
9 changes: 7 additions & 2 deletions keepalived/vrrp/vrrp_iptables.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,8 @@ add_del_igmp_rules(struct ipt_handle *h, int cmd, uint8_t family)

if (h->h6 || (h->h6 = ip6tables_open("filter"))) {
ip6tables_add_rules(h->h6, global_data->vrrp_iptables_outchain, APPEND_RULE, IPSET_DIM_TWO, 0, XTC_LABEL_DROP, NULL, NULL, global_data->vrrp_ipset_mld, IPPROTO_ICMPV6, ICMPV6_MLD2_REPORT, cmd, false);
#ifdef _HAVE_VRRP_VMAC_
ip6tables_add_rules(h->h6, global_data->vrrp_iptables_outchain, APPEND_RULE, IPSET_DIM_TWO, 0, XTC_LABEL_DROP, NULL, NULL, global_data->vrrp_ipset_mld, IPPROTO_ICMPV6, MLD_LISTENER_REPORT, cmd, false);
ip6tables_add_rules(h->h6, global_data->vrrp_iptables_outchain, APPEND_RULE, IPSET_DIM_TWO, IPSET_DIM_ONE_SRC, XTC_LABEL_DROP, NULL, NULL, global_data->vrrp_ipset_vmac_nd, IPPROTO_ICMPV6, ND_NEIGHBOR_ADVERT, cmd, false);
#endif
h->updated_v6 = true;
}
}
Expand Down Expand Up @@ -585,6 +584,12 @@ handle_iptable_rule_for_igmp(const char *ifname, int cmd, int family, struct ipt
XTC_LABEL_DROP, NULL, NULL, NULL, ifname,
family == AF_INET ? IPPROTO_IGMP : IPPROTO_ICMPV6, family == AF_INET ? 0 : ICMPV6_MLD2_REPORT,
cmd, 0, false);

if (family == AF_INET6)
iptables_entry(h, family, global_data->vrrp_iptables_outchain, 0,
XTC_LABEL_DROP, NULL, NULL, NULL, ifname,
IPPROTO_ICMPV6, MLD_LISTENER_REPORT,
cmd, 0, false);
}

static void
Expand Down
52 changes: 43 additions & 9 deletions keepalived/vrrp/vrrp_nftables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1266,15 +1266,15 @@ nft_remove_addresses_iplist(list_head_t *l)
#ifdef _HAVE_VRRP_VMAC_
static struct nftnl_rule *
setup_rule_move_igmp(uint8_t family, const char *table,
const char *chain, const char *handle,
const char *set_map)
const char *chain, const char *set_icmpv6_type,
const char *handle, const char *set_map)
{
/* If have nft dup statement:
nft add rule ip keepalived out ip protocol igmp [meta oifkind macvlan] dup to ip daddr device oif map @vmac_map drop
nft add rule ip6 keepalived out icmpv6 type mld2-listener-report [meta oifkind macvlan] dup to ip6 daddr device oif map @vmac_map drop
nft add rule ip6 keepalived out icmpv6 type @mld-report [meta oifkind macvlan] dup to ip6 daddr device oif map @vmac_map drop
otherwise:
nft add rule ip keepalived out ip protocol igmp [meta oifkind macvlan] oif @vmac_set drop
nft add rule ip6 keepalived out icmpv6 type mld2-listener-report [meta oifkind macvlan] oif @vmac_set drop
nft add rule ip6 keepalived out icmpv6 type @mld-report [meta oifkind macvlan] oif @vmac_set drop
*
* Note: on 3.13 kernels, icmpv6 is specified as @nh,48,8 58
*/
Expand Down Expand Up @@ -1319,8 +1319,7 @@ setup_rule_move_igmp(uint8_t family, const char *table,
add_cmp(r, NFT_REG_1, NFT_CMP_EQ, &protocol, sizeof(protocol));
add_payload(r, NFT_PAYLOAD_TRANSPORT_HEADER, NFT_REG_1,
offsetof(struct icmp6_hdr, icmp6_type), sizeof(icmp6.icmp6_type));
icmp6.icmp6_type = ICMPV6_MLD2_REPORT;
add_cmp(r, NFT_REG_1, NFT_CMP_EQ, &icmp6.icmp6_type, sizeof(icmp6.icmp6_type));
add_lookup(r, NFT_REG_1, NO_REG, set_icmpv6_type, 0, false);
#if HAVE_DECL_NFTA_DUP_MAX
add_payload(r, NFT_PAYLOAD_NETWORK_HEADER, NFT_REG_1,
offsetof(struct ip6_hdr, ip6_dst), sizeof(struct in6_addr));
Expand Down Expand Up @@ -1405,6 +1404,9 @@ nft_setup_igmp(struct mnl_nlmsg_batch *batch, struct nftnl_set **s,
{
struct nlmsghdr *nlh;
struct nftnl_rule *r;
struct nftnl_set *s2;
struct nftnl_set_elem *e;
struct icmp6_hdr icmp6;

if (nfproto == NFPROTO_IPV4) {
if (!ipv4_table_setup)
Expand All @@ -1429,19 +1431,51 @@ nft_setup_igmp(struct mnl_nlmsg_batch *batch, struct nftnl_set **s,
nftnl_set_nlmsg_build_payload(nlh, *s);
my_mnl_nlmsg_batch_next(batch);

#if HAVE_DECL_NFTA_DUP_MAX
if (nfproto == NFPROTO_IPV6) {
#if HAVE_DECL_NFTA_DUP_MAX
*s1 = setup_set(nfproto, global_data->vrrp_nf_table_name, vmac_set_name, NFT_TYPE_IFINDEX, 0, 0);
nlh = nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
NFT_MSG_NEWSET, nfproto,
NLM_F_CREATE|NLM_F_ACK, seq++);

nftnl_set_nlmsg_build_payload(nlh, *s1);
my_mnl_nlmsg_batch_next(batch);
}
#endif

r = setup_rule_move_igmp(nfproto, global_data->vrrp_nf_table_name, "out", NULL, vmac_map_name);
/* nft add set ip6 keepalived mld-report { type icmpv6_type; } */
s2 = setup_set(NFPROTO_IPV6, global_data->vrrp_nf_table_name, "mld-report", NFT_TYPE_ICMPV6_TYPE, 0, 0);

nlh = nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
NFT_MSG_NEWSET, NFPROTO_IPV6,
NLM_F_CREATE|NLM_F_ACK, seq++);
/* set_id = nftnl_set_get_u32(s, NFTNL_SET_ID); */

nftnl_set_set_u32(s2, NFTNL_SET_FLAGS, NFT_SET_CONSTANT);
nftnl_set_set_u32(s2, NFTNL_SET_KEY_LEN, sizeof(icmp6.icmp6_type));

nftnl_set_nlmsg_build_payload(nlh, s2);
my_mnl_nlmsg_batch_next(batch);

/* nft add element ip6 keepalived mld-report { mld2-listener-report, mld-listener-report } */
nlh = nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
NFT_MSG_NEWSETELEM, NFPROTO_IPV6,
NLM_F_CREATE|NLM_F_ACK, seq++);
e = nftnl_set_elem_alloc();
icmp6.icmp6_type = ICMPV6_MLD2_REPORT;
nftnl_set_elem_set(e, NFTNL_SET_ELEM_KEY, &icmp6.icmp6_type, sizeof(icmp6.icmp6_type));
nftnl_set_elem_add(s2, e);

e = nftnl_set_elem_alloc();
icmp6.icmp6_type = MLD_LISTENER_REPORT;
nftnl_set_elem_set(e, NFTNL_SET_ELEM_KEY, &icmp6.icmp6_type, sizeof(icmp6.icmp6_type));
nftnl_set_elem_add(s2, e);

nftnl_set_elems_nlmsg_build_payload(nlh, s2);
nftnl_set_free(s2);
my_mnl_nlmsg_batch_next(batch);
}

r = setup_rule_move_igmp(nfproto, global_data->vrrp_nf_table_name, "out", "mld-report", NULL, vmac_map_name);
nlh = nftnl_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
NFT_MSG_NEWRULE,
nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY),
Expand Down
Loading