Skip to content

Commit c675e06

Browse files
borkmanndavem330
authored andcommitted
ipvlan: decouple l3s mode dependencies from other modes
Right now ipvlan has a hard dependency on CONFIG_NETFILTER and otherwise it cannot be built. However, the only ipvlan operation mode that actually depends on netfilter is l3s, everything else is independent of it. Break this hard dependency such that users are able to use ipvlan l3 mode on systems where netfilter is not compiled in. Therefore, this adds a hidden CONFIG_IPVLAN_L3S bool which is defaulting to y when CONFIG_NETFILTER is set in order to retain existing behavior for l3s. All l3s related code is refactored into ipvlan_l3s.c that is compiled in when enabled. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Mahesh Bandewar <maheshb@google.com> Cc: Florian Westphal <fw@strlen.de> Cc: Martynas Pumputis <m@lambda.lt> Acked-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 998a8a8 commit c675e06

File tree

6 files changed

+287
-208
lines changed

6 files changed

+287
-208
lines changed

drivers/net/Kconfig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,15 @@ config MACVTAP
145145
To compile this driver as a module, choose M here: the module
146146
will be called macvtap.
147147

148+
config IPVLAN_L3S
149+
depends on NETFILTER
150+
def_bool y
151+
select NET_L3_MASTER_DEV
148152

149153
config IPVLAN
150154
tristate "IP-VLAN support"
151155
depends on INET
152156
depends on IPV6 || !IPV6
153-
depends on NETFILTER
154-
select NET_L3_MASTER_DEV
155157
---help---
156158
This allows one to create virtual devices off of a main interface
157159
and packets will be delivered based on the dest L3 (IPv6/IPv4 addr)

drivers/net/ipvlan/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
obj-$(CONFIG_IPVLAN) += ipvlan.o
66
obj-$(CONFIG_IPVTAP) += ipvtap.o
77

8-
ipvlan-objs := ipvlan_core.o ipvlan_main.o
8+
ipvlan-objs-$(CONFIG_IPVLAN_L3S) += ipvlan_l3s.o
9+
ipvlan-objs := ipvlan_core.o ipvlan_main.o $(ipvlan-objs-y)

drivers/net/ipvlan/ipvlan.h

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,9 @@ struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan,
165165
const void *iaddr, bool is_v6);
166166
bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6);
167167
void ipvlan_ht_addr_del(struct ipvl_addr *addr);
168-
struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, struct sk_buff *skb,
169-
u16 proto);
170-
unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
171-
const struct nf_hook_state *state);
168+
struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h,
169+
int addr_type, bool use_dest);
170+
void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type);
172171
void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
173172
unsigned int len, bool success, bool mcast);
174173
int ipvlan_link_new(struct net *src_net, struct net_device *dev,
@@ -177,6 +176,36 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
177176
void ipvlan_link_delete(struct net_device *dev, struct list_head *head);
178177
void ipvlan_link_setup(struct net_device *dev);
179178
int ipvlan_link_register(struct rtnl_link_ops *ops);
179+
#ifdef CONFIG_IPVLAN_L3S
180+
int ipvlan_l3s_register(struct ipvl_port *port);
181+
void ipvlan_l3s_unregister(struct ipvl_port *port);
182+
void ipvlan_migrate_l3s_hook(struct net *oldnet, struct net *newnet);
183+
int ipvlan_l3s_init(void);
184+
void ipvlan_l3s_cleanup(void);
185+
#else
186+
static inline int ipvlan_l3s_register(struct ipvl_port *port)
187+
{
188+
return -ENOTSUPP;
189+
}
190+
191+
static inline void ipvlan_l3s_unregister(struct ipvl_port *port)
192+
{
193+
}
194+
195+
static inline void ipvlan_migrate_l3s_hook(struct net *oldnet,
196+
struct net *newnet)
197+
{
198+
}
199+
200+
static inline int ipvlan_l3s_init(void)
201+
{
202+
return 0;
203+
}
204+
205+
static inline void ipvlan_l3s_cleanup(void)
206+
{
207+
}
208+
#endif /* CONFIG_IPVLAN_L3S */
180209

181210
static inline bool netif_is_ipvlan_port(const struct net_device *dev)
182211
{

drivers/net/ipvlan/ipvlan_core.c

Lines changed: 7 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6)
138138
return ret;
139139
}
140140

141-
static void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type)
141+
void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type)
142142
{
143143
void *lyr3h = NULL;
144144

@@ -355,9 +355,8 @@ static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff **pskb,
355355
return ret;
356356
}
357357

358-
static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port,
359-
void *lyr3h, int addr_type,
360-
bool use_dest)
358+
struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h,
359+
int addr_type, bool use_dest)
361360
{
362361
struct ipvl_addr *addr = NULL;
363362

@@ -647,7 +646,9 @@ int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
647646
case IPVLAN_MODE_L2:
648647
return ipvlan_xmit_mode_l2(skb, dev);
649648
case IPVLAN_MODE_L3:
649+
#ifdef CONFIG_IPVLAN_L3S
650650
case IPVLAN_MODE_L3S:
651+
#endif
651652
return ipvlan_xmit_mode_l3(skb, dev);
652653
}
653654

@@ -743,8 +744,10 @@ rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb)
743744
return ipvlan_handle_mode_l2(pskb, port);
744745
case IPVLAN_MODE_L3:
745746
return ipvlan_handle_mode_l3(pskb, port);
747+
#ifdef CONFIG_IPVLAN_L3S
746748
case IPVLAN_MODE_L3S:
747749
return RX_HANDLER_PASS;
750+
#endif
748751
}
749752

750753
/* Should not reach here */
@@ -753,97 +756,3 @@ rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb)
753756
kfree_skb(skb);
754757
return RX_HANDLER_CONSUMED;
755758
}
756-
757-
static struct ipvl_addr *ipvlan_skb_to_addr(struct sk_buff *skb,
758-
struct net_device *dev)
759-
{
760-
struct ipvl_addr *addr = NULL;
761-
struct ipvl_port *port;
762-
void *lyr3h;
763-
int addr_type;
764-
765-
if (!dev || !netif_is_ipvlan_port(dev))
766-
goto out;
767-
768-
port = ipvlan_port_get_rcu(dev);
769-
if (!port || port->mode != IPVLAN_MODE_L3S)
770-
goto out;
771-
772-
lyr3h = ipvlan_get_L3_hdr(port, skb, &addr_type);
773-
if (!lyr3h)
774-
goto out;
775-
776-
addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true);
777-
out:
778-
return addr;
779-
}
780-
781-
struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, struct sk_buff *skb,
782-
u16 proto)
783-
{
784-
struct ipvl_addr *addr;
785-
struct net_device *sdev;
786-
787-
addr = ipvlan_skb_to_addr(skb, dev);
788-
if (!addr)
789-
goto out;
790-
791-
sdev = addr->master->dev;
792-
switch (proto) {
793-
case AF_INET:
794-
{
795-
int err;
796-
struct iphdr *ip4h = ip_hdr(skb);
797-
798-
err = ip_route_input_noref(skb, ip4h->daddr, ip4h->saddr,
799-
ip4h->tos, sdev);
800-
if (unlikely(err))
801-
goto out;
802-
break;
803-
}
804-
#if IS_ENABLED(CONFIG_IPV6)
805-
case AF_INET6:
806-
{
807-
struct dst_entry *dst;
808-
struct ipv6hdr *ip6h = ipv6_hdr(skb);
809-
int flags = RT6_LOOKUP_F_HAS_SADDR;
810-
struct flowi6 fl6 = {
811-
.flowi6_iif = sdev->ifindex,
812-
.daddr = ip6h->daddr,
813-
.saddr = ip6h->saddr,
814-
.flowlabel = ip6_flowinfo(ip6h),
815-
.flowi6_mark = skb->mark,
816-
.flowi6_proto = ip6h->nexthdr,
817-
};
818-
819-
skb_dst_drop(skb);
820-
dst = ip6_route_input_lookup(dev_net(sdev), sdev, &fl6,
821-
skb, flags);
822-
skb_dst_set(skb, dst);
823-
break;
824-
}
825-
#endif
826-
default:
827-
break;
828-
}
829-
830-
out:
831-
return skb;
832-
}
833-
834-
unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
835-
const struct nf_hook_state *state)
836-
{
837-
struct ipvl_addr *addr;
838-
unsigned int len;
839-
840-
addr = ipvlan_skb_to_addr(skb, skb->dev);
841-
if (!addr)
842-
goto out;
843-
844-
skb->dev = addr->master->dev;
845-
len = skb->len + ETH_HLEN;
846-
ipvlan_count_rx(addr->master, len, true, false);
847-
out:
848-
return NF_ACCEPT;
849-
}

0 commit comments

Comments
 (0)