Skip to content

Commit 20e6133

Browse files
committed
Merge branch 'l3mdev-send-enslaved'
David Ahern says: ==================== net: l3mdev: Allow send on enslaved interface First patch preps for the second. The second is required for several use cases such as ping on an interface and BFD that need to send packets on a specific interface, including ones enslaved to a VRF device. v2 - fixed brackets on both patches per comment from DaveM ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 27c0f73 + 1ff23be commit 20e6133

File tree

5 files changed

+73
-54
lines changed

5 files changed

+73
-54
lines changed

drivers/net/vrf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ static int vrf_get_saddr(struct net_device *dev, struct flowi4 *fl4)
648648

649649
fl4->flowi4_flags |= FLOWI_FLAG_SKIP_NH_OIF;
650650
fl4->flowi4_iif = LOOPBACK_IFINDEX;
651+
/* make sure oif is set to VRF device for lookup */
652+
fl4->flowi4_oif = dev->ifindex;
651653
fl4->flowi4_tos = tos & IPTOS_RT_MASK;
652654
fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
653655
RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);

include/net/l3mdev.h

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -130,52 +130,9 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
130130
return rc;
131131
}
132132

133-
static inline int l3mdev_get_saddr(struct net *net, int ifindex,
134-
struct flowi4 *fl4)
135-
{
136-
struct net_device *dev;
137-
int rc = 0;
138-
139-
if (ifindex) {
140-
141-
rcu_read_lock();
142-
143-
dev = dev_get_by_index_rcu(net, ifindex);
144-
if (dev && netif_is_l3_master(dev) &&
145-
dev->l3mdev_ops->l3mdev_get_saddr) {
146-
rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
147-
}
148-
149-
rcu_read_unlock();
150-
}
151-
152-
return rc;
153-
}
133+
int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4);
154134

155-
static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
156-
const struct flowi6 *fl6)
157-
{
158-
if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rt6_dst)
159-
return dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
160-
161-
return NULL;
162-
}
163-
164-
static inline
165-
struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
166-
const struct flowi6 *fl6)
167-
{
168-
struct dst_entry *dst = NULL;
169-
struct net_device *dev;
170-
171-
dev = dev_get_by_index(net, fl6->flowi6_oif);
172-
if (dev) {
173-
dst = l3mdev_get_rt6_dst(dev, fl6);
174-
dev_put(dev);
175-
}
176-
177-
return dst;
178-
}
135+
struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6);
179136

180137
#else
181138

@@ -233,14 +190,7 @@ static inline int l3mdev_get_saddr(struct net *net, int ifindex,
233190
}
234191

235192
static inline
236-
struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
237-
const struct flowi6 *fl6)
238-
{
239-
return NULL;
240-
}
241-
static inline
242-
struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
243-
const struct flowi6 *fl6)
193+
struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6)
244194
{
245195
return NULL;
246196
}

net/ipv4/route.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,7 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
21462146
unsigned int flags = 0;
21472147
struct fib_result res;
21482148
struct rtable *rth;
2149+
int master_idx;
21492150
int orig_oif;
21502151
int err = -ENETUNREACH;
21512152

@@ -2155,6 +2156,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
21552156

21562157
orig_oif = fl4->flowi4_oif;
21572158

2159+
master_idx = l3mdev_master_ifindex_by_index(net, fl4->flowi4_oif);
2160+
if (master_idx)
2161+
fl4->flowi4_oif = master_idx;
21582162
fl4->flowi4_iif = LOOPBACK_IFINDEX;
21592163
fl4->flowi4_tos = tos & IPTOS_RT_MASK;
21602164
fl4->flowi4_scope = ((tos & RTO_ONLINK) ?

net/ipv6/route.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
11901190
struct dst_entry *dst;
11911191
bool any_src;
11921192

1193-
dst = l3mdev_rt6_dst_by_oif(net, fl6);
1193+
dst = l3mdev_get_rt6_dst(net, fl6);
11941194
if (dst)
11951195
return dst;
11961196

net/l3mdev/l3mdev.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,66 @@ u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
9797
return tb_id;
9898
}
9999
EXPORT_SYMBOL_GPL(l3mdev_fib_table_by_index);
100+
101+
/**
102+
* l3mdev_get_rt6_dst - IPv6 route lookup based on flow. Returns
103+
* cached route for L3 master device if relevant
104+
* to flow
105+
* @net: network namespace for device index lookup
106+
* @fl6: IPv6 flow struct for lookup
107+
*/
108+
109+
struct dst_entry *l3mdev_get_rt6_dst(struct net *net,
110+
const struct flowi6 *fl6)
111+
{
112+
struct dst_entry *dst = NULL;
113+
struct net_device *dev;
114+
115+
if (fl6->flowi6_oif) {
116+
rcu_read_lock();
117+
118+
dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
119+
if (dev && netif_is_l3_slave(dev))
120+
dev = netdev_master_upper_dev_get_rcu(dev);
121+
122+
if (dev && netif_is_l3_master(dev) &&
123+
dev->l3mdev_ops->l3mdev_get_rt6_dst)
124+
dst = dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
125+
126+
rcu_read_unlock();
127+
}
128+
129+
return dst;
130+
}
131+
EXPORT_SYMBOL_GPL(l3mdev_get_rt6_dst);
132+
133+
/**
134+
* l3mdev_get_saddr - get source address for a flow based on an interface
135+
* enslaved to an L3 master device
136+
* @net: network namespace for device index lookup
137+
* @ifindex: Interface index
138+
* @fl4: IPv4 flow struct
139+
*/
140+
141+
int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4)
142+
{
143+
struct net_device *dev;
144+
int rc = 0;
145+
146+
if (ifindex) {
147+
rcu_read_lock();
148+
149+
dev = dev_get_by_index_rcu(net, ifindex);
150+
if (dev && netif_is_l3_slave(dev))
151+
dev = netdev_master_upper_dev_get_rcu(dev);
152+
153+
if (dev && netif_is_l3_master(dev) &&
154+
dev->l3mdev_ops->l3mdev_get_saddr)
155+
rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
156+
157+
rcu_read_unlock();
158+
}
159+
160+
return rc;
161+
}
162+
EXPORT_SYMBOL_GPL(l3mdev_get_saddr);

0 commit comments

Comments
 (0)