mirror of https://gitee.com/openkylin/linux.git
openvswitch: call only into reachable nf-nat code
The openvswitch code has gained support for calling into the
nf-nat-ipv4/ipv6 modules, however those can be loadable modules
in a configuration in which openvswitch is built-in, leading
to link errors:
net/built-in.o: In function `__ovs_ct_lookup':
:(.text+0x2cc2c8): undefined reference to `nf_nat_icmp_reply_translation'
:(.text+0x2cc66c): undefined reference to `nf_nat_icmpv6_reply_translation'
The dependency on (!NF_NAT || NF_NAT) prevents similar issues,
but NF_NAT is set to 'y' if any of the symbols selecting
it are built-in, but the link error happens when any of them
are modular.
A second issue is that even if CONFIG_NF_NAT_IPV6 is built-in,
CONFIG_NF_NAT_IPV4 might be completely disabled. This is unlikely
to be useful in practice, but the driver currently only handles
IPv6 being optional.
This patch improves the Kconfig dependency so that openvswitch
cannot be built-in if either of the two other symbols are set
to 'm', and it replaces the incorrect #ifdef in ovs_ct_nat_execute()
with two "if (IS_ENABLED())" checks that should catch all corner
cases also make the code more readable.
The same #ifdef exists ovs_ct_nat_to_attr(), where it does not
cause a link error, but for consistency I'm changing it the same
way.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Fixes: 05752523e5
("openvswitch: Interface with NAT.")
Acked-by: Joe Stringer <joe@ovn.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
5745b0be05
commit
99b7248e2a
|
@ -7,7 +7,9 @@ config OPENVSWITCH
|
||||||
depends on INET
|
depends on INET
|
||||||
depends on !NF_CONNTRACK || \
|
depends on !NF_CONNTRACK || \
|
||||||
(NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \
|
(NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \
|
||||||
(!NF_NAT || NF_NAT)))
|
(!NF_NAT || NF_NAT) && \
|
||||||
|
(!NF_NAT_IPV4 || NF_NAT_IPV4) && \
|
||||||
|
(!NF_NAT_IPV6 || NF_NAT_IPV6)))
|
||||||
select LIBCRC32C
|
select LIBCRC32C
|
||||||
select MPLS
|
select MPLS
|
||||||
select NET_MPLS_GSO
|
select NET_MPLS_GSO
|
||||||
|
|
|
@ -535,14 +535,15 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
|
||||||
switch (ctinfo) {
|
switch (ctinfo) {
|
||||||
case IP_CT_RELATED:
|
case IP_CT_RELATED:
|
||||||
case IP_CT_RELATED_REPLY:
|
case IP_CT_RELATED_REPLY:
|
||||||
if (skb->protocol == htons(ETH_P_IP) &&
|
if (IS_ENABLED(CONFIG_NF_NAT_IPV4) &&
|
||||||
|
skb->protocol == htons(ETH_P_IP) &&
|
||||||
ip_hdr(skb)->protocol == IPPROTO_ICMP) {
|
ip_hdr(skb)->protocol == IPPROTO_ICMP) {
|
||||||
if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo,
|
if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo,
|
||||||
hooknum))
|
hooknum))
|
||||||
err = NF_DROP;
|
err = NF_DROP;
|
||||||
goto push;
|
goto push;
|
||||||
#if IS_ENABLED(CONFIG_NF_NAT_IPV6)
|
} else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) &&
|
||||||
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
skb->protocol == htons(ETH_P_IPV6)) {
|
||||||
__be16 frag_off;
|
__be16 frag_off;
|
||||||
u8 nexthdr = ipv6_hdr(skb)->nexthdr;
|
u8 nexthdr = ipv6_hdr(skb)->nexthdr;
|
||||||
int hdrlen = ipv6_skip_exthdr(skb,
|
int hdrlen = ipv6_skip_exthdr(skb,
|
||||||
|
@ -557,7 +558,6 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
|
||||||
err = NF_DROP;
|
err = NF_DROP;
|
||||||
goto push;
|
goto push;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/* Non-ICMP, fall thru to initialize if needed. */
|
/* Non-ICMP, fall thru to initialize if needed. */
|
||||||
case IP_CT_NEW:
|
case IP_CT_NEW:
|
||||||
|
@ -1239,7 +1239,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->range.flags & NF_NAT_RANGE_MAP_IPS) {
|
if (info->range.flags & NF_NAT_RANGE_MAP_IPS) {
|
||||||
if (info->family == NFPROTO_IPV4) {
|
if (IS_ENABLED(CONFIG_NF_NAT_IPV4) &&
|
||||||
|
info->family == NFPROTO_IPV4) {
|
||||||
if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN,
|
if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN,
|
||||||
info->range.min_addr.ip) ||
|
info->range.min_addr.ip) ||
|
||||||
(info->range.max_addr.ip
|
(info->range.max_addr.ip
|
||||||
|
@ -1247,8 +1248,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info,
|
||||||
(nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX,
|
(nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX,
|
||||||
info->range.max_addr.ip))))
|
info->range.max_addr.ip))))
|
||||||
return false;
|
return false;
|
||||||
#if IS_ENABLED(CONFIG_NF_NAT_IPV6)
|
} else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) &&
|
||||||
} else if (info->family == NFPROTO_IPV6) {
|
info->family == NFPROTO_IPV6) {
|
||||||
if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN,
|
if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN,
|
||||||
&info->range.min_addr.in6) ||
|
&info->range.min_addr.in6) ||
|
||||||
(memcmp(&info->range.max_addr.in6,
|
(memcmp(&info->range.max_addr.in6,
|
||||||
|
@ -1257,7 +1258,6 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info,
|
||||||
(nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MAX,
|
(nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MAX,
|
||||||
&info->range.max_addr.in6))))
|
&info->range.max_addr.in6))))
|
||||||
return false;
|
return false;
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue