Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14452ca3 authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan Committed by David S. Miller
Browse files

net: qualcomm: rmnet: Export mux_id and flags to netlink



Define new netlink attributes for rmnet mux_id and flags. These
flags / mux_id were earlier using vlan flags / id respectively.
The flag bits are also moved to uapi and are renamed with
prefix RMNET_FLAG_*.

Also add the rmnet policy to handle the new netlink attributes.

Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 378e2535
Loading
Loading
Loading
Loading
+25 −16
Original line number Original line Diff line number Diff line
@@ -43,6 +43,11 @@


/* Local Definitions and Declarations */
/* Local Definitions and Declarations */


static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = {
	[IFLA_RMNET_MUX_ID]	= { .type = NLA_U16 },
	[IFLA_RMNET_FLAGS]	= { .len = sizeof(struct ifla_rmnet_flags) },
};

static int rmnet_is_real_dev_registered(const struct net_device *real_dev)
static int rmnet_is_real_dev_registered(const struct net_device *real_dev)
{
{
	return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler;
	return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler;
@@ -131,7 +136,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
			 struct nlattr *tb[], struct nlattr *data[],
			 struct nlattr *tb[], struct nlattr *data[],
			 struct netlink_ext_ack *extack)
			 struct netlink_ext_ack *extack)
{
{
	u32 data_format = RMNET_INGRESS_FORMAT_DEAGGREGATION;
	u32 data_format = RMNET_FLAGS_INGRESS_DEAGGREGATION;
	struct net_device *real_dev;
	struct net_device *real_dev;
	int mode = RMNET_EPMODE_VND;
	int mode = RMNET_EPMODE_VND;
	struct rmnet_endpoint *ep;
	struct rmnet_endpoint *ep;
@@ -143,14 +148,14 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
	if (!real_dev || !dev)
	if (!real_dev || !dev)
		return -ENODEV;
		return -ENODEV;


	if (!data[IFLA_VLAN_ID])
	if (!data[IFLA_RMNET_MUX_ID])
		return -EINVAL;
		return -EINVAL;


	ep = kzalloc(sizeof(*ep), GFP_ATOMIC);
	ep = kzalloc(sizeof(*ep), GFP_ATOMIC);
	if (!ep)
	if (!ep)
		return -ENOMEM;
		return -ENOMEM;


	mux_id = nla_get_u16(data[IFLA_VLAN_ID]);
	mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);


	err = rmnet_register_real_device(real_dev);
	err = rmnet_register_real_device(real_dev);
	if (err)
	if (err)
@@ -165,10 +170,10 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,


	hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
	hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);


	if (data[IFLA_VLAN_FLAGS]) {
	if (data[IFLA_RMNET_FLAGS]) {
		struct ifla_vlan_flags *flags;
		struct ifla_rmnet_flags *flags;


		flags = nla_data(data[IFLA_VLAN_FLAGS]);
		flags = nla_data(data[IFLA_RMNET_FLAGS]);
		data_format = flags->flags & flags->mask;
		data_format = flags->flags & flags->mask;
	}
	}


@@ -276,10 +281,10 @@ static int rmnet_rtnl_validate(struct nlattr *tb[], struct nlattr *data[],
{
{
	u16 mux_id;
	u16 mux_id;


	if (!data || !data[IFLA_VLAN_ID])
	if (!data || !data[IFLA_RMNET_MUX_ID])
		return -EINVAL;
		return -EINVAL;


	mux_id = nla_get_u16(data[IFLA_VLAN_ID]);
	mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
	if (mux_id > (RMNET_MAX_LOGICAL_EP - 1))
	if (mux_id > (RMNET_MAX_LOGICAL_EP - 1))
		return -ERANGE;
		return -ERANGE;


@@ -304,8 +309,8 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],


	port = rmnet_get_port_rtnl(real_dev);
	port = rmnet_get_port_rtnl(real_dev);


	if (data[IFLA_VLAN_ID]) {
	if (data[IFLA_RMNET_MUX_ID]) {
		mux_id = nla_get_u16(data[IFLA_VLAN_ID]);
		mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
		ep = rmnet_get_endpoint(port, priv->mux_id);
		ep = rmnet_get_endpoint(port, priv->mux_id);


		hlist_del_init_rcu(&ep->hlnode);
		hlist_del_init_rcu(&ep->hlnode);
@@ -315,10 +320,10 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
		priv->mux_id = mux_id;
		priv->mux_id = mux_id;
	}
	}


	if (data[IFLA_VLAN_FLAGS]) {
	if (data[IFLA_RMNET_FLAGS]) {
		struct ifla_vlan_flags *flags;
		struct ifla_rmnet_flags *flags;


		flags = nla_data(data[IFLA_VLAN_FLAGS]);
		flags = nla_data(data[IFLA_RMNET_FLAGS]);
		port->data_format = flags->flags & flags->mask;
		port->data_format = flags->flags & flags->mask;
	}
	}


@@ -327,13 +332,16 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],


static size_t rmnet_get_size(const struct net_device *dev)
static size_t rmnet_get_size(const struct net_device *dev)
{
{
	return nla_total_size(2) /* IFLA_VLAN_ID */ +
	return
	       nla_total_size(sizeof(struct ifla_vlan_flags)); /* IFLA_VLAN_FLAGS */
		/* IFLA_RMNET_MUX_ID */
		nla_total_size(2) +
		/* IFLA_RMNET_FLAGS */
		nla_total_size(sizeof(struct ifla_rmnet_flags));
}
}


struct rtnl_link_ops rmnet_link_ops __read_mostly = {
struct rtnl_link_ops rmnet_link_ops __read_mostly = {
	.kind		= "rmnet",
	.kind		= "rmnet",
	.maxtype	= __IFLA_VLAN_MAX,
	.maxtype	= __IFLA_RMNET_MAX,
	.priv_size	= sizeof(struct rmnet_priv),
	.priv_size	= sizeof(struct rmnet_priv),
	.setup		= rmnet_vnd_setup,
	.setup		= rmnet_vnd_setup,
	.validate	= rmnet_rtnl_validate,
	.validate	= rmnet_rtnl_validate,
@@ -341,6 +349,7 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = {
	.dellink	= rmnet_dellink,
	.dellink	= rmnet_dellink,
	.get_size	= rmnet_get_size,
	.get_size	= rmnet_get_size,
	.changelink     = rmnet_changelink,
	.changelink     = rmnet_changelink,
	.policy		= rmnet_policy,
};
};


/* Needs either rcu_read_lock() or rtnl lock */
/* Needs either rcu_read_lock() or rtnl lock */
+5 −5
Original line number Original line Diff line number Diff line
@@ -70,7 +70,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
	u8 mux_id;
	u8 mux_id;


	if (RMNET_MAP_GET_CD_BIT(skb)) {
	if (RMNET_MAP_GET_CD_BIT(skb)) {
		if (port->data_format & RMNET_INGRESS_FORMAT_MAP_COMMANDS)
		if (port->data_format & RMNET_FLAGS_INGRESS_MAP_COMMANDS)
			return rmnet_map_command(skb, port);
			return rmnet_map_command(skb, port);


		goto free_skb;
		goto free_skb;
@@ -93,7 +93,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
	skb_pull(skb, sizeof(struct rmnet_map_header));
	skb_pull(skb, sizeof(struct rmnet_map_header));
	rmnet_set_skb_proto(skb);
	rmnet_set_skb_proto(skb);


	if (port->data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4) {
	if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) {
		if (!rmnet_map_checksum_downlink_packet(skb, len + pad))
		if (!rmnet_map_checksum_downlink_packet(skb, len + pad))
			skb->ip_summed = CHECKSUM_UNNECESSARY;
			skb->ip_summed = CHECKSUM_UNNECESSARY;
	}
	}
@@ -121,7 +121,7 @@ rmnet_map_ingress_handler(struct sk_buff *skb,
		skb_push(skb, ETH_HLEN);
		skb_push(skb, ETH_HLEN);
	}
	}


	if (port->data_format & RMNET_INGRESS_FORMAT_DEAGGREGATION) {
	if (port->data_format & RMNET_FLAGS_INGRESS_DEAGGREGATION) {
		while ((skbn = rmnet_map_deaggregate(skb, port)) != NULL)
		while ((skbn = rmnet_map_deaggregate(skb, port)) != NULL)
			__rmnet_map_ingress_handler(skbn, port);
			__rmnet_map_ingress_handler(skbn, port);


@@ -141,7 +141,7 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
	additional_header_len = 0;
	additional_header_len = 0;
	required_headroom = sizeof(struct rmnet_map_header);
	required_headroom = sizeof(struct rmnet_map_header);


	if (port->data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4) {
	if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4) {
		additional_header_len = sizeof(struct rmnet_map_ul_csum_header);
		additional_header_len = sizeof(struct rmnet_map_ul_csum_header);
		required_headroom += additional_header_len;
		required_headroom += additional_header_len;
	}
	}
@@ -151,7 +151,7 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
			goto fail;
			goto fail;
	}
	}


	if (port->data_format & RMNET_EGRESS_FORMAT_MAP_CKSUMV4)
	if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4)
		rmnet_map_checksum_uplink_packet(skb, orig_dev);
		rmnet_map_checksum_uplink_packet(skb, orig_dev);


	map_header = rmnet_map_add_map_header(skb, additional_header_len, 0);
	map_header = rmnet_map_add_map_header(skb, additional_header_len, 0);
+1 −1
Original line number Original line Diff line number Diff line
@@ -69,7 +69,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
	struct rmnet_map_control_command *cmd;
	struct rmnet_map_control_command *cmd;
	int xmit_status;
	int xmit_status;


	if (port->data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4) {
	if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) {
		if (skb->len < sizeof(struct rmnet_map_header) +
		if (skb->len < sizeof(struct rmnet_map_header) +
		    RMNET_MAP_GET_LENGTH(skb) +
		    RMNET_MAP_GET_LENGTH(skb) +
		    sizeof(struct rmnet_map_dl_csum_trailer)) {
		    sizeof(struct rmnet_map_dl_csum_trailer)) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -309,7 +309,7 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
	maph = (struct rmnet_map_header *)skb->data;
	maph = (struct rmnet_map_header *)skb->data;
	packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header);
	packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header);


	if (port->data_format & RMNET_INGRESS_FORMAT_MAP_CKSUMV4)
	if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
		packet_len += sizeof(struct rmnet_map_dl_csum_trailer);
		packet_len += sizeof(struct rmnet_map_dl_csum_trailer);


	if (((int)skb->len - (int)packet_len) < 0)
	if (((int)skb->len - (int)packet_len) < 0)
+0 −6
Original line number Original line Diff line number Diff line
@@ -18,12 +18,6 @@
#define RMNET_NEEDED_HEADROOM      16
#define RMNET_NEEDED_HEADROOM      16
#define RMNET_TX_QUEUE_LEN         1000
#define RMNET_TX_QUEUE_LEN         1000


/* Constants */
#define RMNET_INGRESS_FORMAT_DEAGGREGATION      BIT(0)
#define RMNET_INGRESS_FORMAT_MAP_COMMANDS       BIT(1)
#define RMNET_INGRESS_FORMAT_MAP_CKSUMV4        BIT(2)
#define RMNET_EGRESS_FORMAT_MAP_CKSUMV4         BIT(3)

/* Replace skb->dev to a virtual rmnet device and pass up the stack */
/* Replace skb->dev to a virtual rmnet device and pass up the stack */
#define RMNET_EPMODE_VND (1)
#define RMNET_EPMODE_VND (1)
/* Pass the frame directly to another device with dev_queue_xmit() */
/* Pass the frame directly to another device with dev_queue_xmit() */
Loading