Skip to content

Commit 1e75701

Browse files
committed
Merge branch 'rmnet-Configuration-options'
Subash Abhinov Kasiviswanathan says: ==================== net: qualcomm: rmnet: Configuration options This series adds support for configuring features on rmnet devices. The rmnet specific features to be configured here are aggregation and control commands. Patch 1 is a cleanup of return codes in the transmit path. Patch 2 removes some redundant ingress and egress macros. Patch 3 restricts the creation of rmnet dev to one dev per mux id for a given real dev. Patch 4 adds ethernet data path support. Patches 5-6 add support for configuring features on new and existing rmnet devices. v1->v2: The memory leak fixed as part of patch 1 is merged seperately as a896d94abd2c ("net: qualcomm: rmnet: Fix leak on transmit failure"). Fix a use after free in patch 4 if a packet with headroom lesser than ethernet header length is received. v2->v3: Fix formatting problem in patch 5 in the return statement. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents b4f70c3 + 23790ef commit 1e75701

File tree

6 files changed

+78
-51
lines changed

6 files changed

+78
-51
lines changed

drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
143143
struct nlattr *tb[], struct nlattr *data[],
144144
struct netlink_ext_ack *extack)
145145
{
146-
int ingress_format = RMNET_INGRESS_FORMAT_DEMUXING |
147-
RMNET_INGRESS_FORMAT_DEAGGREGATION |
148-
RMNET_INGRESS_FORMAT_MAP;
149-
int egress_format = RMNET_EGRESS_FORMAT_MUXING |
150-
RMNET_EGRESS_FORMAT_MAP;
146+
int ingress_format = RMNET_INGRESS_FORMAT_DEAGGREGATION;
151147
struct net_device *real_dev;
152148
int mode = RMNET_EPMODE_VND;
153149
struct rmnet_endpoint *ep;
@@ -181,13 +177,20 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
181177
if (err)
182178
goto err2;
183179

184-
netdev_dbg(dev, "data format [ingress 0x%08X] [egress 0x%08X]\n",
185-
ingress_format, egress_format);
186-
port->egress_data_format = egress_format;
187-
port->ingress_data_format = ingress_format;
188180
port->rmnet_mode = mode;
189181

190182
hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
183+
184+
if (data[IFLA_VLAN_FLAGS]) {
185+
struct ifla_vlan_flags *flags;
186+
187+
flags = nla_data(data[IFLA_VLAN_FLAGS]);
188+
ingress_format = flags->flags & flags->mask;
189+
}
190+
191+
netdev_dbg(dev, "data format [ingress 0x%08X]\n", ingress_format);
192+
port->ingress_data_format = ingress_format;
193+
191194
return 0;
192195

193196
err2:
@@ -317,9 +320,49 @@ static int rmnet_rtnl_validate(struct nlattr *tb[], struct nlattr *data[],
317320
return 0;
318321
}
319322

323+
static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
324+
struct nlattr *data[],
325+
struct netlink_ext_ack *extack)
326+
{
327+
struct rmnet_priv *priv = netdev_priv(dev);
328+
struct net_device *real_dev;
329+
struct rmnet_endpoint *ep;
330+
struct rmnet_port *port;
331+
u16 mux_id;
332+
333+
real_dev = __dev_get_by_index(dev_net(dev),
334+
nla_get_u32(tb[IFLA_LINK]));
335+
336+
if (!real_dev || !dev || !rmnet_is_real_dev_registered(real_dev))
337+
return -ENODEV;
338+
339+
port = rmnet_get_port_rtnl(real_dev);
340+
341+
if (data[IFLA_VLAN_ID]) {
342+
mux_id = nla_get_u16(data[IFLA_VLAN_ID]);
343+
ep = rmnet_get_endpoint(port, priv->mux_id);
344+
345+
hlist_del_init_rcu(&ep->hlnode);
346+
hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
347+
348+
ep->mux_id = mux_id;
349+
priv->mux_id = mux_id;
350+
}
351+
352+
if (data[IFLA_VLAN_FLAGS]) {
353+
struct ifla_vlan_flags *flags;
354+
355+
flags = nla_data(data[IFLA_VLAN_FLAGS]);
356+
port->ingress_data_format = flags->flags & flags->mask;
357+
}
358+
359+
return 0;
360+
}
361+
320362
static size_t rmnet_get_size(const struct net_device *dev)
321363
{
322-
return nla_total_size(2); /* IFLA_VLAN_ID */
364+
return nla_total_size(2) /* IFLA_VLAN_ID */ +
365+
nla_total_size(sizeof(struct ifla_vlan_flags)); /* IFLA_VLAN_FLAGS */
323366
}
324367

325368
struct rtnl_link_ops rmnet_link_ops __read_mostly = {
@@ -331,6 +374,7 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = {
331374
.newlink = rmnet_newlink,
332375
.dellink = rmnet_dellink,
333376
.get_size = rmnet_get_size,
377+
.changelink = rmnet_changelink,
334378
};
335379

336380
/* Needs either rcu_read_lock() or rtnl lock */

drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ struct rmnet_endpoint {
3333
struct rmnet_port {
3434
struct net_device *dev;
3535
u32 ingress_data_format;
36-
u32 egress_data_format;
3736
u8 nr_rmnet_devs;
3837
u8 rmnet_mode;
3938
struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP];

drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <linux/netdevice.h>
1717
#include <linux/netdev_features.h>
18+
#include <linux/if_arp.h>
1819
#include "rmnet_private.h"
1920
#include "rmnet_config.h"
2021
#include "rmnet_vnd.h"
@@ -104,6 +105,15 @@ rmnet_map_ingress_handler(struct sk_buff *skb,
104105
{
105106
struct sk_buff *skbn;
106107

108+
if (skb->dev->type == ARPHRD_ETHER) {
109+
if (pskb_expand_head(skb, ETH_HLEN, 0, GFP_KERNEL)) {
110+
kfree_skb(skb);
111+
return;
112+
}
113+
114+
skb_push(skb, ETH_HLEN);
115+
}
116+
107117
if (port->ingress_data_format & RMNET_INGRESS_FORMAT_DEAGGREGATION) {
108118
while ((skbn = rmnet_map_deaggregate(skb)) != NULL)
109119
__rmnet_map_ingress_handler(skbn, port);
@@ -133,20 +143,18 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
133143
if (!map_header)
134144
goto fail;
135145

136-
if (port->egress_data_format & RMNET_EGRESS_FORMAT_MUXING) {
137-
if (mux_id == 0xff)
138-
map_header->mux_id = 0;
139-
else
140-
map_header->mux_id = mux_id;
141-
}
146+
if (mux_id == 0xff)
147+
map_header->mux_id = 0;
148+
else
149+
map_header->mux_id = mux_id;
142150

143151
skb->protocol = htons(ETH_P_MAP);
144152

145-
return RMNET_MAP_SUCCESS;
153+
return 0;
146154

147155
fail:
148156
kfree_skb(skb);
149-
return RMNET_MAP_CONSUMED;
157+
return -ENOMEM;
150158
}
151159

152160
static void
@@ -178,8 +186,7 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)
178186

179187
switch (port->rmnet_mode) {
180188
case RMNET_EPMODE_VND:
181-
if (port->ingress_data_format & RMNET_INGRESS_FORMAT_MAP)
182-
rmnet_map_ingress_handler(skb, port);
189+
rmnet_map_ingress_handler(skb, port);
183190
break;
184191
case RMNET_EPMODE_BRIDGE:
185192
rmnet_bridge_handler(skb, port->bridge_ep);
@@ -212,19 +219,8 @@ void rmnet_egress_handler(struct sk_buff *skb)
212219
return;
213220
}
214221

215-
if (port->egress_data_format & RMNET_EGRESS_FORMAT_MAP) {
216-
switch (rmnet_map_egress_handler(skb, port, mux_id, orig_dev)) {
217-
case RMNET_MAP_CONSUMED:
218-
return;
219-
220-
case RMNET_MAP_SUCCESS:
221-
break;
222-
223-
default:
224-
kfree_skb(skb);
225-
return;
226-
}
227-
}
222+
if (rmnet_map_egress_handler(skb, port, mux_id, orig_dev))
223+
return;
228224

229225
rmnet_vnd_tx_fixup(skb, orig_dev);
230226

drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,6 @@ struct rmnet_map_control_command {
3030
};
3131
} __aligned(1);
3232

33-
enum rmnet_map_results {
34-
RMNET_MAP_SUCCESS,
35-
RMNET_MAP_CONSUMED,
36-
RMNET_MAP_GENERAL_FAILURE,
37-
RMNET_MAP_NOT_ENABLED,
38-
RMNET_MAP_FAILED_AGGREGATION,
39-
RMNET_MAP_FAILED_MUX
40-
};
41-
4233
enum rmnet_map_commands {
4334
RMNET_MAP_COMMAND_NONE,
4435
RMNET_MAP_COMMAND_FLOW_DISABLE,

drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,8 @@
1919
#define RMNET_TX_QUEUE_LEN 1000
2020

2121
/* Constants */
22-
#define RMNET_EGRESS_FORMAT_MAP BIT(1)
23-
#define RMNET_EGRESS_FORMAT_AGGREGATION BIT(2)
24-
#define RMNET_EGRESS_FORMAT_MUXING BIT(3)
25-
26-
#define RMNET_INGRESS_FORMAT_MAP BIT(1)
27-
#define RMNET_INGRESS_FORMAT_DEAGGREGATION BIT(2)
28-
#define RMNET_INGRESS_FORMAT_DEMUXING BIT(3)
29-
#define RMNET_INGRESS_FORMAT_MAP_COMMANDS BIT(4)
22+
#define RMNET_INGRESS_FORMAT_DEAGGREGATION BIT(0)
23+
#define RMNET_INGRESS_FORMAT_MAP_COMMANDS BIT(1)
3024

3125
/* Replace skb->dev to a virtual rmnet device and pass up the stack */
3226
#define RMNET_EPMODE_VND (1)

drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
185185
if (ep->egress_dev)
186186
return -EINVAL;
187187

188+
if (rmnet_get_endpoint(port, id))
189+
return -EBUSY;
190+
188191
rc = register_netdevice(rmnet_dev);
189192
if (!rc) {
190193
ep->egress_dev = rmnet_dev;

0 commit comments

Comments
 (0)