[PATCH v3] netfilter: nf_conntrack_sip: add sip_external_media logic
From: Alin Nastac Allow media streams that are not passing through this router. When enabled, the sip_external_media logic will leave SDP payload untouched when it detects that interface towards INVITEd party is the same with the one towards media endpoint. Signed-off-by: Alin Nastac --- net/netfilter/nf_conntrack_sip.c | 42 1 file changed, 42 insertions(+) diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index c8d2b66..f067c6b 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include @@ -54,6 +56,11 @@ module_param(sip_direct_media, int, 0600); MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " "endpoints only (default 1)"); +static int sip_external_media __read_mostly = 0; +module_param(sip_external_media, int, 0600); +MODULE_PARM_DESC(sip_external_media, "Expect Media streams between external " +"endpoints (default 0)"); + const struct nf_nat_sip_hooks *nf_nat_sip_hooks; EXPORT_SYMBOL_GPL(nf_nat_sip_hooks); @@ -861,6 +868,41 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, if (!nf_inet_addr_cmp(daddr, >tuplehash[dir].tuple.src.u3)) return NF_ACCEPT; saddr = >tuplehash[!dir].tuple.src.u3; + } else if (sip_external_media) { + struct net_device *dev = skb_dst(skb)->dev; + struct net *net = dev_net(dev); + struct rtable *rt; + struct flowi4 fl4 = {}; +#if IS_ENABLED(CONFIG_IPV6) + struct flowi6 fl6 = {}; +#endif + struct dst_entry *dst = NULL; + + switch (nf_ct_l3num(ct)) { + case NFPROTO_IPV4: + fl4.daddr = daddr->ip; + rt = ip_route_output_key(net, ); + if (!IS_ERR(rt)) + dst = >dst; + break; + +#if IS_ENABLED(CONFIG_IPV6) + case NFPROTO_IPV6: + fl6.daddr = daddr->in6; + dst = ip6_route_output(net, NULL, ); + if (dst->error) { + dst_release(dst); + dst = NULL; + } + break; +#endif + } + + /* Don't predict any conntracks when media endpoint is reachable +* through the same interface as the signalling peer. +*/ + if (dst && dst->dev == dev) + return NF_ACCEPT; } /* We need to check whether the registration exists before attempting -- 2.7.4
[PATCH v2] netfilter: nf_conntrack_sip: add sip_external_media logic
From: Alin Nastac Allow media streams that are not passing through this router. When enabled, the sip_external_media logic will leave SDP payload untouched when it detects that interface towards INVITEd party is the same with the one towards media endpoint. Signed-off-by: Alin Nastac --- net/netfilter/nf_conntrack_sip.c | 40 1 file changed, 40 insertions(+) diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index c8d2b66..f09a0e1 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include @@ -54,6 +56,11 @@ module_param(sip_direct_media, int, 0600); MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " "endpoints only (default 1)"); +static int sip_external_media __read_mostly = 0; +module_param(sip_external_media, int, 0600); +MODULE_PARM_DESC(sip_external_media, "Expect Media streams between external " +"endpoints (default 0)"); + const struct nf_nat_sip_hooks *nf_nat_sip_hooks; EXPORT_SYMBOL_GPL(nf_nat_sip_hooks); @@ -861,6 +868,39 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, if (!nf_inet_addr_cmp(daddr, >tuplehash[dir].tuple.src.u3)) return NF_ACCEPT; saddr = >tuplehash[!dir].tuple.src.u3; + } else if (sip_external_media) { + struct net_device *dev = skb_dst(skb)->dev; + struct net *net = dev_net(dev); + struct rtable *rt; + struct flowi4 fl4 = {}; + struct flowi6 fl6 = {}; + struct dst_entry *dst = NULL; + + switch (nf_ct_l3num(ct)) { + case NFPROTO_IPV4: + fl4.daddr = daddr->ip; + rt = ip_route_output_key(net, ); + if (!IS_ERR(rt)) + dst = >dst; + break; + +#if IS_ENABLED(CONFIG_IPV6) + case NFPROTO_IPV6: + fl6.daddr = daddr->in6; + dst = ip6_route_output(net, NULL, ); + if (dst->error) { + dst_release(dst); + dst = NULL; + } + break; +#endif + } + + /* Don't predict any conntracks when media endpoint is reachable +* through the same interface as the signalling peer. +*/ + if (dst && dst->dev == dev) + return NF_ACCEPT; } /* We need to check whether the registration exists before attempting -- 2.7.4
[PATCH] netfilter: nf_conntrack_sip: add sip_external_media logic
Allow media streams that are not passing through this router. When enabled, the sip_external_media logic will leave SDP payload untouched when it detects that interface towards INVITEd party is the same with the one towards media endpoint. Signed-off-by: Alin Nastac --- net/netfilter/nf_conntrack_sip.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index c8d2b66..5416c08 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include @@ -54,6 +56,11 @@ module_param(sip_direct_media, int, 0600); MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " "endpoints only (default 1)"); +static int sip_external_media __read_mostly = 0; +module_param(sip_external_media, int, 0600); +MODULE_PARM_DESC(sip_external_media, "Expect Media streams between external " +"endpoints (default 0)"); + const struct nf_nat_sip_hooks *nf_nat_sip_hooks; EXPORT_SYMBOL_GPL(nf_nat_sip_hooks); @@ -861,6 +868,37 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, if (!nf_inet_addr_cmp(daddr, >tuplehash[dir].tuple.src.u3)) return NF_ACCEPT; saddr = >tuplehash[!dir].tuple.src.u3; + } else if (sip_external_media) { + struct net_device *dev = skb_dst(skb)->dev; + struct net *net = dev_net(dev); + struct rtable *rt; + struct flowi4 fl4 = {}; + struct flowi6 fl6 = {}; + struct dst_entry *dst = NULL; + + switch (nf_ct_l3num(ct)) { + case NFPROTO_IPV4: + fl4.daddr = daddr->ip; + rt = ip_route_output_key(net, ); + if (!IS_ERR(rt)) + dst = >dst; + break; + + case NFPROTO_IPV6: + fl6.daddr = daddr->in6; + dst = ip6_route_output(net, NULL, ); + if (dst->error) { + dst_release(dst); + dst = NULL; + } + break; + } + + /* Don't predict any conntracks when media endpoint is reachable +* through the same interface as the signalling peer. +*/ + if (dst && dst->dev == dev) + return NF_ACCEPT; } /* We need to check whether the registration exists before attempting -- 2.7.4
[PATCH] netfilter: nf_nat_sip: fix RTP/RTCP source port translations
Perform the same SNAT translation on RTP/RTCP conntracks regardless of who sends the first datagram. Prior to this change, RTP packets send by the peer who required source port translation were forwarded with unmodified source port when this peer started its voice/video stream first. Signed-off-by: Alin Nastac --- net/netfilter/nf_nat_sip.c | 35 +++ 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index 1f30860..a1e23cc 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -316,6 +317,9 @@ static void nf_nat_sip_seq_adjust(struct sk_buff *skb, unsigned int protoff, static void nf_nat_sip_expected(struct nf_conn *ct, struct nf_conntrack_expect *exp) { + struct nf_conn_help *help = nfct_help(ct->master); + struct nf_conntrack_expect *pair_exp; + int range_set_for_snat = 0; struct nf_nat_range2 range; /* This must be a fresh one. */ @@ -327,15 +331,38 @@ static void nf_nat_sip_expected(struct nf_conn *ct, range.min_addr = range.max_addr = exp->saved_addr; nf_nat_setup_info(ct, , NF_NAT_MANIP_DST); - /* Change src to where master sends to, but only if the connection -* actually came from the same source. */ - if (nf_inet_addr_cmp(>tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, + /* Do SRC manip according with the parameters found in the +* paired expected conntrack. */ + spin_lock_bh(_conntrack_expect_lock); + hlist_for_each_entry(pair_exp, >expectations, lnode) { + if (pair_exp->tuple.src.l3num == nf_ct_l3num(ct) && + pair_exp->tuple.dst.protonum == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum && + nf_inet_addr_cmp(>tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, _exp->saved_addr) && + ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all == pair_exp->saved_proto.all) { + range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED); + range.min_proto.all = range.max_proto.all = pair_exp->tuple.dst.u.all; + range.min_addr = range.max_addr = pair_exp->tuple.dst.u3; + range_set_for_snat = 1; + break; + } + } + spin_unlock_bh(_conntrack_expect_lock); + + /* When no paired expected conntrack has been found, change src to +* where master sends to, but only if the connection actually came +* from the same source. */ + if (!range_set_for_snat && + nf_inet_addr_cmp(>tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, >master->tuplehash[exp->dir].tuple.src.u3)) { range.flags = NF_NAT_RANGE_MAP_IPS; range.min_addr = range.max_addr = ct->master->tuplehash[!exp->dir].tuple.dst.u3; - nf_nat_setup_info(ct, , NF_NAT_MANIP_SRC); + range_set_for_snat = 1; } + + /* Perform SRC manip. */ + if (range_set_for_snat) + nf_nat_setup_info(ct, , NF_NAT_MANIP_SRC); } static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff, -- 2.7.4
[PATCH v2] ipv6: Preserve link scope traffic original oif
When ip6_route_me_harder is invoked, it resets outgoing interface of: - link-local scoped packets sent by neighbor discovery - multicast packets sent by MLD host - multicast packets send by MLD proxy daemon that sets outgoing interface through IPV6_PKTINFO ipi6_ifindex Link-local and multicast packets must keep their original oif after ip6_route_me_harder is called. Signed-off-by: Alin Nastac --- net/ipv6/netfilter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 5ae8e1c..8b075f0 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -24,7 +24,8 @@ int ip6_route_me_harder(struct net *net, struct sk_buff *skb) unsigned int hh_len; struct dst_entry *dst; struct flowi6 fl6 = { - .flowi6_oif = sk ? sk->sk_bound_dev_if : 0, + .flowi6_oif = sk && sk->sk_bound_dev_if ? sk->sk_bound_dev_if : + rt6_need_strict(>daddr) ? skb_dst(skb)->dev->ifindex : 0, .flowi6_mark = skb->mark, .flowi6_uid = sock_net_uid(net, sk), .daddr = iph->daddr, -- 2.7.4
[PATCH v2] ipv6: Preserve link scope traffic original oif
When ip6_route_me_harder is invoked, it resets outgoing interface of: - link-local scoped packets sent by neighbor discovery - multicast packets sent by MLD host - multicast packets send by MLD proxy daemon that sets outgoing interface through IPV6_PKTINFO ipi6_ifindex Link-local and multicast packets must keep their original oif after ip6_route_me_harder is called. --- net/ipv6/netfilter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 5ae8e1c..8b075f0 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -24,7 +24,8 @@ int ip6_route_me_harder(struct net *net, struct sk_buff *skb) unsigned int hh_len; struct dst_entry *dst; struct flowi6 fl6 = { - .flowi6_oif = sk ? sk->sk_bound_dev_if : 0, + .flowi6_oif = sk && sk->sk_bound_dev_if ? sk->sk_bound_dev_if : + rt6_need_strict(>daddr) ? skb_dst(skb)->dev->ifindex : 0, .flowi6_mark = skb->mark, .flowi6_uid = sock_net_uid(net, sk), .daddr = iph->daddr, -- 2.7.4
[PATCH] netfilter: nf_nat_sip: fix RTP/RTCP source port translations
Perform the same SNAT translation on RTP/RTCP conntracks regardless of who sends the first datagram. Prior to this change, RTP packets send by the peer who required source port translation were forwarded with unmodified source port when this peer started its voice/video stream first. --- net/netfilter/nf_nat_sip.c | 35 +++ 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index 1f30860..a1e23cc 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -316,6 +317,9 @@ static void nf_nat_sip_seq_adjust(struct sk_buff *skb, unsigned int protoff, static void nf_nat_sip_expected(struct nf_conn *ct, struct nf_conntrack_expect *exp) { + struct nf_conn_help *help = nfct_help(ct->master); + struct nf_conntrack_expect *pair_exp; + int range_set_for_snat = 0; struct nf_nat_range2 range; /* This must be a fresh one. */ @@ -327,15 +331,38 @@ static void nf_nat_sip_expected(struct nf_conn *ct, range.min_addr = range.max_addr = exp->saved_addr; nf_nat_setup_info(ct, , NF_NAT_MANIP_DST); - /* Change src to where master sends to, but only if the connection -* actually came from the same source. */ - if (nf_inet_addr_cmp(>tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, + /* Do SRC manip according with the parameters found in the +* paired expected conntrack. */ + spin_lock_bh(_conntrack_expect_lock); + hlist_for_each_entry(pair_exp, >expectations, lnode) { + if (pair_exp->tuple.src.l3num == nf_ct_l3num(ct) && + pair_exp->tuple.dst.protonum == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum && + nf_inet_addr_cmp(>tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, _exp->saved_addr) && + ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all == pair_exp->saved_proto.all) { + range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED); + range.min_proto.all = range.max_proto.all = pair_exp->tuple.dst.u.all; + range.min_addr = range.max_addr = pair_exp->tuple.dst.u3; + range_set_for_snat = 1; + break; + } + } + spin_unlock_bh(_conntrack_expect_lock); + + /* When no paired expected conntrack has been found, change src to +* where master sends to, but only if the connection actually came +* from the same source. */ + if (!range_set_for_snat && + nf_inet_addr_cmp(>tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, >master->tuplehash[exp->dir].tuple.src.u3)) { range.flags = NF_NAT_RANGE_MAP_IPS; range.min_addr = range.max_addr = ct->master->tuplehash[!exp->dir].tuple.dst.u3; - nf_nat_setup_info(ct, , NF_NAT_MANIP_SRC); + range_set_for_snat = 1; } + + /* Perform SRC manip. */ + if (range_set_for_snat) + nf_nat_setup_info(ct, , NF_NAT_MANIP_SRC); } static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff, -- 2.7.4
[PATCH] netfilter: add grev6 conntrack support
From: Alin Nastac nf_conntrack_proto_generic refuse to handle grev6 packets when NF_CT_PROTO_GRE is enabled, resulting in grev6 packets being categorized as INVALID. --- net/netfilter/nf_conntrack_proto_gre.c | 49 +- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 650eb4f..c6b249d 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -380,19 +380,60 @@ static const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = { .init_net = gre_init_net, }; +static const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre6 = { + .l3proto = AF_INET6, + .l4proto = IPPROTO_GRE, + .pkt_to_tuple= gre_pkt_to_tuple, +#ifdef CONFIG_NF_CONNTRACK_PROCFS + .print_conntrack = gre_print_conntrack, +#endif + .packet = gre_packet, + .new = gre_new, + .destroy = gre_destroy, + .me = THIS_MODULE, +#if IS_ENABLED(CONFIG_NF_CT_NETLINK) + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, + .nla_policy = nf_ct_port_nla_policy, +#endif +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + .ctnl_timeout= { + .nlattr_to_obj = gre_timeout_nlattr_to_obj, + .obj_to_nlattr = gre_timeout_obj_to_nlattr, + .nlattr_max = CTA_TIMEOUT_GRE_MAX, + .obj_size = sizeof(unsigned int) * GRE_CT_MAX, + .nla_policy = gre_timeout_nla_policy, + }, +#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ + .net_id = _gre_net_id, + .init_net = gre_init_net, +}; + static int proto_gre_net_init(struct net *net) { int ret = 0; ret = nf_ct_l4proto_pernet_register_one(net, _conntrack_l4proto_gre4); - if (ret < 0) + if (ret < 0) { pr_err("nf_conntrack_gre4: pernet registration failed.\n"); + return ret; + } + + ret = nf_ct_l4proto_pernet_register_one(net, + _conntrack_l4proto_gre6); + if (ret < 0) { + pr_err("nf_conntrack_gre6: pernet registration failed.\n"); + nf_ct_l4proto_pernet_unregister_one(net, _conntrack_l4proto_gre4); + } + return ret; } static void proto_gre_net_exit(struct net *net) { + nf_ct_l4proto_pernet_unregister_one(net, _conntrack_l4proto_gre6); nf_ct_l4proto_pernet_unregister_one(net, _conntrack_l4proto_gre4); nf_ct_gre_keymap_flush(net); } @@ -414,8 +455,13 @@ static int __init nf_ct_proto_gre_init(void) ret = nf_ct_l4proto_register_one(_conntrack_l4proto_gre4); if (ret < 0) goto out_gre4; + ret = nf_ct_l4proto_register_one(_conntrack_l4proto_gre6); + if (ret < 0) + goto out_gre6; return 0; +out_gre6: + nf_ct_l4proto_unregister_one(_conntrack_l4proto_gre4); out_gre4: unregister_pernet_subsys(_gre_net_ops); out_pernet: @@ -424,6 +470,7 @@ static int __init nf_ct_proto_gre_init(void) static void __exit nf_ct_proto_gre_fini(void) { + nf_ct_l4proto_unregister_one(_conntrack_l4proto_gre6); nf_ct_l4proto_unregister_one(_conntrack_l4proto_gre4); unregister_pernet_subsys(_gre_net_ops); } -- 2.7.4
[PATCH] ebtables: fix compat entry padding
On arm64, ebt_entry_{match,watcher,target} structs are 40 bytes long while on 32-bit arm these structs have a size of 36 bytes. COMPAT_XT_ALIGN() macro cannot be used here to determine the necessary padding for the CONFIG_COMPAT because it imposes an 8-byte boundary alignment, condition that is not found in 32-bit ebtables application. Signed-off-by: Alin Nastac --- net/bridge/netfilter/ebtables.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 28a4c34..91cf3df 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1610,16 +1610,16 @@ struct compat_ebt_entry_mwt { compat_uptr_t ptr; } u; compat_uint_t match_size; - compat_uint_t data[0]; + compat_uint_t data[0] __attribute__ ((aligned (__alignof__(struct compat_ebt_replace; }; /* account for possible padding between match_size and ->data */ static int ebt_compat_entry_padsize(void) { - BUILD_BUG_ON(XT_ALIGN(sizeof(struct ebt_entry_match)) < - COMPAT_XT_ALIGN(sizeof(struct compat_ebt_entry_mwt))); - return (int) XT_ALIGN(sizeof(struct ebt_entry_match)) - - COMPAT_XT_ALIGN(sizeof(struct compat_ebt_entry_mwt)); + BUILD_BUG_ON(sizeof(struct ebt_entry_match) < + sizeof(struct compat_ebt_entry_mwt)); + return (int) sizeof(struct ebt_entry_match) - + sizeof(struct compat_ebt_entry_mwt); } static int ebt_compat_match_offset(const struct xt_match *match, -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ebtables: fix limit and mark modules incompatibilities between 32-bit user space and 64-bit kernel space
Signed-off-by: Alin Nastac <alin.nas...@gmail.com> --- include/linux/netfilter_bridge/ebt_limit.h | 4 include/linux/netfilter_bridge/ebt_mark_m.h | 5 + include/linux/netfilter_bridge/ebt_mark_t.h | 4 3 files changed, 13 insertions(+) diff --git a/include/linux/netfilter_bridge/ebt_limit.h b/include/linux/netfilter_bridge/ebt_limit.h index 66d80b3..6db2443 100644 --- a/include/linux/netfilter_bridge/ebt_limit.h +++ b/include/linux/netfilter_bridge/ebt_limit.h @@ -16,7 +16,11 @@ struct ebt_limit_info { __u32 burst; /* Period multiplier for upper limit. */ /* Used internally by the kernel */ +#ifdef KERNEL_64_USERSPACE_32 + uint64_t prev; +#else unsigned long prev; +#endif __u32 credit; __u32 credit_cap, cost; }; diff --git a/include/linux/netfilter_bridge/ebt_mark_m.h b/include/linux/netfilter_bridge/ebt_mark_m.h index 410f9e5..017307f 100644 --- a/include/linux/netfilter_bridge/ebt_mark_m.h +++ b/include/linux/netfilter_bridge/ebt_mark_m.h @@ -7,7 +7,12 @@ #define EBT_MARK_OR 0x02 #define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR) struct ebt_mark_m_info { +#ifdef KERNEL_64_USERSPACE_32 + union { uint64_t pad1; unsigned long mark; }; + union { uint64_t pad2; unsigned long mask; }; +#else unsigned long mark, mask; +#endif __u8 invert; __u8 bitmask; }; diff --git a/include/linux/netfilter_bridge/ebt_mark_t.h b/include/linux/netfilter_bridge/ebt_mark_t.h index 7d5a268..5f0f6d5 100644 --- a/include/linux/netfilter_bridge/ebt_mark_t.h +++ b/include/linux/netfilter_bridge/ebt_mark_t.h @@ -14,7 +14,11 @@ #define MARK_XOR_VALUE (0xffc0) struct ebt_mark_t_info { +#ifdef KERNEL_64_USERSPACE_32 + union { uint64_t pad; unsigned long mark; }; +#else unsigned long mark; +#endif /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ int target; }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] extensions: libxt_hashlimit: fix uint64_t printf formats
From: Alin Nastac <alin.nas...@gmail.com> The remaining %llu formats are used for unsigned long long values. Signed-off-by: Alin Nastac <alin.nas...@gmail.com> --- extensions/libxt_hashlimit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c index 9e63e1e..d7de540 100644 --- a/extensions/libxt_hashlimit.c +++ b/extensions/libxt_hashlimit.c @@ -736,7 +736,7 @@ hashlimit_mt_print(const struct hashlimit_cfg2 *cfg, unsigned int dmask, int rev quantum = print_bytes(cfg->avg, cfg->burst, ""); } else { quantum = print_rate(cfg->avg, revision); - printf(" burst %llu", cfg->burst); + printf(" burst %"PRIu64, cfg->burst); } if (cfg->mode & (XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT)) { @@ -846,7 +846,7 @@ hashlimit_mt_save(const struct hashlimit_cfg2 *cfg, const char* name, unsigned i quantum = print_bytes(cfg->avg, cfg->burst, "--hashlimit-"); } else { quantum = print_rate(cfg->avg, revision); - printf(" --hashlimit-burst %llu", cfg->burst); + printf(" --hashlimit-burst %"PRIu64, cfg->burst); } if (cfg->mode & (XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | @@ -942,7 +942,7 @@ static void print_packets_rate_xlate(struct xt_xlate *xl, uint64_t avg, _rates[i].mult / avg < _rates[i].mult % avg) break; - xt_xlate_add(xl, " %llu/%s burst %lu packets", + xt_xlate_add(xl, " %"PRIu64"/%s burst %"PRIu64" packets", _rates[i-1].mult / avg, _rates[i-1].name, burst); } -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] extensions: libxt_hashlimit: fix 64-bit printf formats
Furthermore, this extension use a mix of PRIu64 and %llu formats for uint64_t values. IMO it should use only one, for the sake of consistency. Signed-off-by: Alin Nastac <alin.nas...@gmail.com> --- extensions/libxt_hashlimit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c index 9e63e1e..970bad9 100644 --- a/extensions/libxt_hashlimit.c +++ b/extensions/libxt_hashlimit.c @@ -942,7 +942,7 @@ static void print_packets_rate_xlate(struct xt_xlate *xl, uint64_t avg, _rates[i].mult / avg < _rates[i].mult % avg) break; - xt_xlate_add(xl, " %llu/%s burst %lu packets", + xt_xlate_add(xl, " %"PRIu64"/%s burst %"PRIu64" packets", _rates[i-1].mult / avg, _rates[i-1].name, burst); } -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] netfilter: Parse ICMPv6 redirects
Extract IPv6 packet that triggered the sending of redirect message from ICMPv6 Redirected Header option and check if conntrack table contain such connection. Mark redirect packet as RELATED if a matching connection is found. Signed-off-by: Alin Nastac <alin.nas...@gmail.com> --- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 87 -- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index d2c2ccb..f7bae5c 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -144,7 +144,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, static int icmpv6_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, -unsigned int icmp6off, +unsigned int inneripv6off, unsigned int hooknum) { struct nf_conntrack_tuple intuple, origtuple; @@ -157,9 +157,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, /* Are they talking about one of our connections? */ if (!nf_ct_get_tuplepr(skb, - skb_network_offset(skb) - + sizeof(struct ipv6hdr) - + sizeof(struct icmp6hdr), + inneripv6off, PF_INET6, net, )) { pr_debug("icmpv6_error: Can't get tuple\n"); return -NF_ACCEPT; @@ -194,6 +192,82 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, } static int +icmpv6_redirect_message(struct net *net, struct nf_conn *tmpl, +struct sk_buff *skb, +unsigned int dataoff, +unsigned int hooknum) +{ + const struct in6_addr *dst; + struct in6_addr _dst; + const struct nd_opt_hdr *opt; + struct nd_opt_hdr _opt; + const struct ipv6hdr *iph; + struct ipv6hdr _iph; + + /* skip target address */ + dataoff += sizeof(_dst); + + /* read destination address */ + dst = skb_header_pointer(skb, dataoff, sizeof(_dst), &_dst); + if (dst == NULL) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: short redirect packet "); + return -NF_ACCEPT; + } + if (ipv6_addr_is_multicast(dst)) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: redirect destination address is multicast "); + return -NF_ACCEPT; + } + dataoff += sizeof(_dst); + + /* find redirected header */ + while (1) { + opt = skb_header_pointer(skb, dataoff, sizeof(_opt), &_opt); + if (opt == NULL) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: invalid redirect option "); + return -NF_ACCEPT; + } + if (opt->nd_opt_len == 0) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: invalid redirect option length "); + return -NF_ACCEPT; + } + + if (opt->nd_opt_type == ND_OPT_REDIRECT_HDR) { + dataoff += 8; + break; + } + + dataoff += opt->nd_opt_len << 3; + } + + /* read redirect header */ + iph = skb_header_pointer(skb, dataoff, sizeof(_iph), &_iph); + if (iph == NULL) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: short redirect header "); + return -NF_ACCEPT; + } + + /* validate destination address */ + if (!ipv6_addr_equal(>daddr, dst)) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: redirect destination address not matching destination address of redirect header "); + return -NF_ACCEPT; + } + + return icmpv6_error_message(net, tmpl, skb, dataoff, hooknum); +} + +static int icmpv6_error(struct net *net, struct nf_conn *tmpl, struct sk_b
[PATCH] netfilter: Parse ICMPv6 redirects
Extract IPv6 packet that triggered the sending of redirect message from ICMPv6 Redirected Header option and check if conntrack table contain such connection. Mark redirect packet as RELATED if a matching connection is found. Signed-off-by: Alin Nastac <alin.nas...@gmail.com> --- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 77 -- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index d2c2ccb..2f9a985 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -144,7 +144,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, static int icmpv6_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, -unsigned int icmp6off, +unsigned int inneripv6off, unsigned int hooknum) { struct nf_conntrack_tuple intuple, origtuple; @@ -157,9 +157,7 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, /* Are they talking about one of our connections? */ if (!nf_ct_get_tuplepr(skb, - skb_network_offset(skb) - + sizeof(struct ipv6hdr) - + sizeof(struct icmp6hdr), + inneripv6off, PF_INET6, net, )) { pr_debug("icmpv6_error: Can't get tuple\n"); return -NF_ACCEPT; @@ -225,9 +223,78 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb, nf_conntrack_get(skb_nfct(skb)); return NF_ACCEPT; } + dataoff += sizeof(struct icmp6hdr); /* is not error message ? */ - if (icmp6h->icmp6_type >= 128) + if (icmp6h->icmp6_type == NDISC_REDIRECT) { + const struct in6_addr *dst; + struct in6_addr _dst; + const struct nd_opt_hdr *opt; + struct nd_opt_hdr _opt; + const struct ipv6hdr *iph; + struct ipv6hdr _iph; + + /* skip target address */ + dataoff += sizeof(_dst); + + /* read destination address */ + dst = skb_header_pointer(skb, dataoff, sizeof(_dst), &_dst); + if (dst == NULL) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: short redirect packet "); + return -NF_ACCEPT; + } + if (ipv6_addr_is_multicast(dst)) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: redirect destination address is multicast "); + return -NF_ACCEPT; + } + dataoff += sizeof(_dst); + + /* find redirected header */ + while (1) { + opt = skb_header_pointer(skb, dataoff, sizeof(_opt), &_opt); + if (opt == NULL) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: invalid redirect option "); + return -NF_ACCEPT; + } + if (opt->nd_opt_len == 0) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: invalid redirect option length "); + return -NF_ACCEPT; + } + + if (opt->nd_opt_type == ND_OPT_REDIRECT_HDR) { + dataoff += 8; + break; + } + + dataoff += opt->nd_opt_len << 3; + } + + /* read redirect header */ + iph = skb_header_pointer(skb, dataoff, sizeof(_iph), &_iph); + if (iph == NULL) { + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(net, PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: short redirect header "); + return -NF_ACCEPT; + } + + /* validate destination address */ +
[PATCH] ipv6: Preserve link scope traffic original oif
Link-local and multicast packets must keep their original oif after ip6_route_me_harder is called. Signed-off-by: Alin Nastac <alin.nas...@gmail.com> --- net/ipv6/netfilter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 39970e2..02811c5 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -24,7 +24,8 @@ int ip6_route_me_harder(struct net *net, struct sk_buff *skb) unsigned int hh_len; struct dst_entry *dst; struct flowi6 fl6 = { - .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, + .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : + rt6_need_strict(>daddr) ? skb_dst(skb)->dev->ifindex : 0, .flowi6_mark = skb->mark, .flowi6_uid = sock_net_uid(net, skb->sk), .daddr = iph->daddr, -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ipv6: Preserve link scope traffic original oif
Link-local and multicast packets must keep their original oif after ip6_route_me_harder is called. Signed-off-by: Alin Nastac <alin.nas...@gmail.com> --- net/ipv6/netfilter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 39970e2..02811c5 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -24,7 +24,8 @@ int ip6_route_me_harder(struct net *net, struct sk_buff *skb) unsigned int hh_len; struct dst_entry *dst; struct flowi6 fl6 = { - .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, + .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : + rt6_need_strict(>daddr) ? skb_dst(skb)->dev->ifindex : 0, .flowi6_mark = skb->mark, .flowi6_uid = sock_net_uid(net, skb->sk), .daddr = iph->daddr, -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html