forked from rpms/kernel
		
	Update team driver from net-next from Jiri Pirko
This commit is contained in:
		
							parent
							
								
									3b7690310e
								
							
						
					
					
						commit
						eb44f89919
					
				| @ -62,7 +62,7 @@ Summary: The Linux kernel | |||||||
| # For non-released -rc kernels, this will be appended after the rcX and | # For non-released -rc kernels, this will be appended after the rcX and | ||||||
| # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" | # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" | ||||||
| # | # | ||||||
| %global baserelease 1 | %global baserelease 2 | ||||||
| %global fedora_build %{baserelease} | %global fedora_build %{baserelease} | ||||||
| 
 | 
 | ||||||
| # base_sublevel is the kernel version we're starting with and patching | # base_sublevel is the kernel version we're starting with and patching | ||||||
| @ -654,6 +654,8 @@ Patch100: taint-vbox.patch | |||||||
| 
 | 
 | ||||||
| Patch110: vmbugon-warnon.patch | Patch110: vmbugon-warnon.patch | ||||||
| 
 | 
 | ||||||
|  | Patch150: team-net-next-20120808.patch | ||||||
|  | 
 | ||||||
| Patch390: linux-2.6-defaults-acpi-video.patch | Patch390: linux-2.6-defaults-acpi-video.patch | ||||||
| Patch391: linux-2.6-acpi-video-dos.patch | Patch391: linux-2.6-acpi-video-dos.patch | ||||||
| Patch394: linux-2.6-acpi-debug-infinite-loop.patch | Patch394: linux-2.6-acpi-debug-infinite-loop.patch | ||||||
| @ -1306,6 +1308,8 @@ ApplyPatch taint-vbox.patch | |||||||
| 
 | 
 | ||||||
| ApplyPatch vmbugon-warnon.patch | ApplyPatch vmbugon-warnon.patch | ||||||
| 
 | 
 | ||||||
|  | ApplyPatch team-net-next-20120808.patch | ||||||
|  | 
 | ||||||
| # Architecture patches | # Architecture patches | ||||||
| # x86(-64) | # x86(-64) | ||||||
| 
 | 
 | ||||||
| @ -2305,6 +2309,9 @@ fi | |||||||
| #                 ||----w | | #                 ||----w | | ||||||
| #                 ||     || | #                 ||     || | ||||||
| %changelog | %changelog | ||||||
|  | * Wed Aug 08 2012 Josh Boyer <jwboyer@redhat.com> - 3.6.0-0.rc1.git2.2 | ||||||
|  | - Update team driver from net-next from Jiri Pirko | ||||||
|  | 
 | ||||||
| * Tue Aug 07 2012 Josh Boyer <jwboyer@redhat.com> | * Tue Aug 07 2012 Josh Boyer <jwboyer@redhat.com> | ||||||
| - Add support for ppc64p7 subarch | - Add support for ppc64p7 subarch | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										499
									
								
								team-net-next-20120808.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										499
									
								
								team-net-next-20120808.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,499 @@ | |||||||
|  | Update team driver to latest net-next. | ||||||
|  | 
 | ||||||
|  | Split patches available here: | ||||||
|  | http://people.redhat.com/jpirko/f18_team_update_2/ | ||||||
|  | 
 | ||||||
|  | Jiri Pirko (4): | ||||||
|  |   netlink: add signed types | ||||||
|  |   team: add signed 32-bit team option type | ||||||
|  |   team: add per port priority option | ||||||
|  |   team: add support for queue override by setting queue_id for port | ||||||
|  | 
 | ||||||
|  |  drivers/net/team/team.c |  200 ++++++++++++++++++++++++++++++++++++++++++++++- | ||||||
|  |  include/linux/if_team.h |    7 ++ | ||||||
|  |  include/net/netlink.h   |   98 +++++++++++++++++++++++ | ||||||
|  |  3 files changed, 303 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Jiri Pirko <jpirko@redhat.com> | ||||||
|  | 
 | ||||||
|  | diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
 | ||||||
|  | index 87707ab..ba10c46 100644
 | ||||||
|  | --- a/drivers/net/team/team.c
 | ||||||
|  | +++ b/drivers/net/team/team.c
 | ||||||
|  | @@ -658,6 +658,122 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb)
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | +/*************************************
 | ||||||
|  | + * Multiqueue Tx port select override
 | ||||||
|  | + *************************************/
 | ||||||
|  | +
 | ||||||
|  | +static int team_queue_override_init(struct team *team)
 | ||||||
|  | +{
 | ||||||
|  | +	struct list_head *listarr;
 | ||||||
|  | +	unsigned int queue_cnt = team->dev->num_tx_queues - 1;
 | ||||||
|  | +	unsigned int i;
 | ||||||
|  | +
 | ||||||
|  | +	if (!queue_cnt)
 | ||||||
|  | +		return 0;
 | ||||||
|  | +	listarr = kmalloc(sizeof(struct list_head) * queue_cnt, GFP_KERNEL);
 | ||||||
|  | +	if (!listarr)
 | ||||||
|  | +		return -ENOMEM;
 | ||||||
|  | +	team->qom_lists = listarr;
 | ||||||
|  | +	for (i = 0; i < queue_cnt; i++)
 | ||||||
|  | +		INIT_LIST_HEAD(listarr++);
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void team_queue_override_fini(struct team *team)
 | ||||||
|  | +{
 | ||||||
|  | +	kfree(team->qom_lists);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static struct list_head *__team_get_qom_list(struct team *team, u16 queue_id)
 | ||||||
|  | +{
 | ||||||
|  | +	return &team->qom_lists[queue_id - 1];
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/*
 | ||||||
|  | + * note: already called with rcu_read_lock
 | ||||||
|  | + */
 | ||||||
|  | +static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb)
 | ||||||
|  | +{
 | ||||||
|  | +	struct list_head *qom_list;
 | ||||||
|  | +	struct team_port *port;
 | ||||||
|  | +
 | ||||||
|  | +	if (!team->queue_override_enabled || !skb->queue_mapping)
 | ||||||
|  | +		return false;
 | ||||||
|  | +	qom_list = __team_get_qom_list(team, skb->queue_mapping);
 | ||||||
|  | +	list_for_each_entry_rcu(port, qom_list, qom_list) {
 | ||||||
|  | +		if (!team_dev_queue_xmit(team, port, skb))
 | ||||||
|  | +			return true;
 | ||||||
|  | +	}
 | ||||||
|  | +	return false;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void __team_queue_override_port_del(struct team *team,
 | ||||||
|  | +					   struct team_port *port)
 | ||||||
|  | +{
 | ||||||
|  | +	list_del_rcu(&port->qom_list);
 | ||||||
|  | +	synchronize_rcu();
 | ||||||
|  | +	INIT_LIST_HEAD(&port->qom_list);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static bool team_queue_override_port_has_gt_prio_than(struct team_port *port,
 | ||||||
|  | +						      struct team_port *cur)
 | ||||||
|  | +{
 | ||||||
|  | +	if (port->priority < cur->priority)
 | ||||||
|  | +		return true;
 | ||||||
|  | +	if (port->priority > cur->priority)
 | ||||||
|  | +		return false;
 | ||||||
|  | +	if (port->index < cur->index)
 | ||||||
|  | +		return true;
 | ||||||
|  | +	return false;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void __team_queue_override_port_add(struct team *team,
 | ||||||
|  | +					   struct team_port *port)
 | ||||||
|  | +{
 | ||||||
|  | +	struct team_port *cur;
 | ||||||
|  | +	struct list_head *qom_list;
 | ||||||
|  | +	struct list_head *node;
 | ||||||
|  | +
 | ||||||
|  | +	if (!port->queue_id || !team_port_enabled(port))
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	qom_list = __team_get_qom_list(team, port->queue_id);
 | ||||||
|  | +	node = qom_list;
 | ||||||
|  | +	list_for_each_entry(cur, qom_list, qom_list) {
 | ||||||
|  | +		if (team_queue_override_port_has_gt_prio_than(port, cur))
 | ||||||
|  | +			break;
 | ||||||
|  | +		node = &cur->qom_list;
 | ||||||
|  | +	}
 | ||||||
|  | +	list_add_tail_rcu(&port->qom_list, node);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void __team_queue_override_enabled_check(struct team *team)
 | ||||||
|  | +{
 | ||||||
|  | +	struct team_port *port;
 | ||||||
|  | +	bool enabled = false;
 | ||||||
|  | +
 | ||||||
|  | +	list_for_each_entry(port, &team->port_list, list) {
 | ||||||
|  | +		if (!list_empty(&port->qom_list)) {
 | ||||||
|  | +			enabled = true;
 | ||||||
|  | +			break;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +	if (enabled == team->queue_override_enabled)
 | ||||||
|  | +		return;
 | ||||||
|  | +	netdev_dbg(team->dev, "%s queue override\n",
 | ||||||
|  | +		   enabled ? "Enabling" : "Disabling");
 | ||||||
|  | +	team->queue_override_enabled = enabled;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void team_queue_override_port_refresh(struct team *team,
 | ||||||
|  | +					     struct team_port *port)
 | ||||||
|  | +{
 | ||||||
|  | +	__team_queue_override_port_del(team, port);
 | ||||||
|  | +	__team_queue_override_port_add(team, port);
 | ||||||
|  | +	__team_queue_override_enabled_check(team);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  |  /**************** | ||||||
|  |   * Port handling | ||||||
|  |   ****************/ | ||||||
|  | @@ -688,6 +804,7 @@ static void team_port_enable(struct team *team,
 | ||||||
|  |  	hlist_add_head_rcu(&port->hlist, | ||||||
|  |  			   team_port_index_hash(team, port->index)); | ||||||
|  |  	team_adjust_ops(team); | ||||||
|  | +	team_queue_override_port_refresh(team, port);
 | ||||||
|  |  	if (team->ops.port_enabled) | ||||||
|  |  		team->ops.port_enabled(team, port); | ||||||
|  |  } | ||||||
|  | @@ -716,6 +833,7 @@ static void team_port_disable(struct team *team,
 | ||||||
|  |  	hlist_del_rcu(&port->hlist); | ||||||
|  |  	__reconstruct_port_hlist(team, port->index); | ||||||
|  |  	port->index = -1; | ||||||
|  | +	team_queue_override_port_refresh(team, port);
 | ||||||
|  |  	__team_adjust_ops(team, team->en_port_count - 1); | ||||||
|  |  	/* | ||||||
|  |  	 * Wait until readers see adjusted ops. This ensures that | ||||||
|  | @@ -881,6 +999,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
 | ||||||
|  |   | ||||||
|  |  	port->dev = port_dev; | ||||||
|  |  	port->team = team; | ||||||
|  | +	INIT_LIST_HEAD(&port->qom_list);
 | ||||||
|  |   | ||||||
|  |  	port->orig.mtu = port_dev->mtu; | ||||||
|  |  	err = dev_set_mtu(port_dev, dev->mtu); | ||||||
|  | @@ -1092,6 +1211,49 @@ static int team_user_linkup_en_option_set(struct team *team,
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int team_priority_option_get(struct team *team,
 | ||||||
|  | +				    struct team_gsetter_ctx *ctx)
 | ||||||
|  | +{
 | ||||||
|  | +	struct team_port *port = ctx->info->port;
 | ||||||
|  | +
 | ||||||
|  | +	ctx->data.s32_val = port->priority;
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static int team_priority_option_set(struct team *team,
 | ||||||
|  | +				    struct team_gsetter_ctx *ctx)
 | ||||||
|  | +{
 | ||||||
|  | +	struct team_port *port = ctx->info->port;
 | ||||||
|  | +
 | ||||||
|  | +	port->priority = ctx->data.s32_val;
 | ||||||
|  | +	team_queue_override_port_refresh(team, port);
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static int team_queue_id_option_get(struct team *team,
 | ||||||
|  | +				    struct team_gsetter_ctx *ctx)
 | ||||||
|  | +{
 | ||||||
|  | +	struct team_port *port = ctx->info->port;
 | ||||||
|  | +
 | ||||||
|  | +	ctx->data.u32_val = port->queue_id;
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static int team_queue_id_option_set(struct team *team,
 | ||||||
|  | +				    struct team_gsetter_ctx *ctx)
 | ||||||
|  | +{
 | ||||||
|  | +	struct team_port *port = ctx->info->port;
 | ||||||
|  | +
 | ||||||
|  | +	if (port->queue_id == ctx->data.u32_val)
 | ||||||
|  | +		return 0;
 | ||||||
|  | +	if (ctx->data.u32_val >= team->dev->real_num_tx_queues)
 | ||||||
|  | +		return -EINVAL;
 | ||||||
|  | +	port->queue_id = ctx->data.u32_val;
 | ||||||
|  | +	team_queue_override_port_refresh(team, port);
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  |  static const struct team_option team_options[] = { | ||||||
|  |  	{ | ||||||
|  |  		.name = "mode", | ||||||
|  | @@ -1120,6 +1282,20 @@ static const struct team_option team_options[] = {
 | ||||||
|  |  		.getter = team_user_linkup_en_option_get, | ||||||
|  |  		.setter = team_user_linkup_en_option_set, | ||||||
|  |  	}, | ||||||
|  | +	{
 | ||||||
|  | +		.name = "priority",
 | ||||||
|  | +		.type = TEAM_OPTION_TYPE_S32,
 | ||||||
|  | +		.per_port = true,
 | ||||||
|  | +		.getter = team_priority_option_get,
 | ||||||
|  | +		.setter = team_priority_option_set,
 | ||||||
|  | +	},
 | ||||||
|  | +	{
 | ||||||
|  | +		.name = "queue_id",
 | ||||||
|  | +		.type = TEAM_OPTION_TYPE_U32,
 | ||||||
|  | +		.per_port = true,
 | ||||||
|  | +		.getter = team_queue_id_option_get,
 | ||||||
|  | +		.setter = team_queue_id_option_set,
 | ||||||
|  | +	},
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static struct lock_class_key team_netdev_xmit_lock_key; | ||||||
|  | @@ -1155,6 +1331,9 @@ static int team_init(struct net_device *dev)
 | ||||||
|  |  	for (i = 0; i < TEAM_PORT_HASHENTRIES; i++) | ||||||
|  |  		INIT_HLIST_HEAD(&team->en_port_hlist[i]); | ||||||
|  |  	INIT_LIST_HEAD(&team->port_list); | ||||||
|  | +	err = team_queue_override_init(team);
 | ||||||
|  | +	if (err)
 | ||||||
|  | +		goto err_team_queue_override_init;
 | ||||||
|  |   | ||||||
|  |  	team_adjust_ops(team); | ||||||
|  |   | ||||||
|  | @@ -1170,6 +1349,8 @@ static int team_init(struct net_device *dev)
 | ||||||
|  |  	return 0; | ||||||
|  |   | ||||||
|  |  err_options_register: | ||||||
|  | +	team_queue_override_fini(team);
 | ||||||
|  | +err_team_queue_override_init:
 | ||||||
|  |  	free_percpu(team->pcpu_stats); | ||||||
|  |   | ||||||
|  |  	return err; | ||||||
|  | @@ -1187,6 +1368,7 @@ static void team_uninit(struct net_device *dev)
 | ||||||
|  |   | ||||||
|  |  	__team_change_mode(team, NULL); /* cleanup */ | ||||||
|  |  	__team_options_unregister(team, team_options, ARRAY_SIZE(team_options)); | ||||||
|  | +	team_queue_override_fini(team);
 | ||||||
|  |  	mutex_unlock(&team->lock); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1216,10 +1398,12 @@ static int team_close(struct net_device *dev)
 | ||||||
|  |  static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev) | ||||||
|  |  { | ||||||
|  |  	struct team *team = netdev_priv(dev); | ||||||
|  | -	bool tx_success = false;
 | ||||||
|  | +	bool tx_success;
 | ||||||
|  |  	unsigned int len = skb->len; | ||||||
|  |   | ||||||
|  | -	tx_success = team->ops.transmit(team, skb);
 | ||||||
|  | +	tx_success = team_queue_override_transmit(team, skb);
 | ||||||
|  | +	if (!tx_success)
 | ||||||
|  | +		tx_success = team->ops.transmit(team, skb);
 | ||||||
|  |  	if (tx_success) { | ||||||
|  |  		struct team_pcpu_stats *pcpu_stats; | ||||||
|  |   | ||||||
|  | @@ -1787,6 +1971,12 @@ static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team,
 | ||||||
|  |  		    nla_put_flag(skb, TEAM_ATTR_OPTION_DATA)) | ||||||
|  |  			goto nest_cancel; | ||||||
|  |  		break; | ||||||
|  | +	case TEAM_OPTION_TYPE_S32:
 | ||||||
|  | +		if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_S32))
 | ||||||
|  | +			goto nest_cancel;
 | ||||||
|  | +		if (nla_put_s32(skb, TEAM_ATTR_OPTION_DATA, ctx.data.s32_val))
 | ||||||
|  | +			goto nest_cancel;
 | ||||||
|  | +		break;
 | ||||||
|  |  	default: | ||||||
|  |  		BUG(); | ||||||
|  |  	} | ||||||
|  | @@ -1975,6 +2165,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
 | ||||||
|  |  		case NLA_FLAG: | ||||||
|  |  			opt_type = TEAM_OPTION_TYPE_BOOL; | ||||||
|  |  			break; | ||||||
|  | +		case NLA_S32:
 | ||||||
|  | +			opt_type = TEAM_OPTION_TYPE_S32;
 | ||||||
|  | +			break;
 | ||||||
|  |  		default: | ||||||
|  |  			goto team_put; | ||||||
|  |  		} | ||||||
|  | @@ -2031,6 +2224,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
 | ||||||
|  |  			case TEAM_OPTION_TYPE_BOOL: | ||||||
|  |  				ctx.data.bool_val = attr_data ? true : false; | ||||||
|  |  				break; | ||||||
|  | +			case TEAM_OPTION_TYPE_S32:
 | ||||||
|  | +				ctx.data.s32_val = nla_get_s32(attr_data);
 | ||||||
|  | +				break;
 | ||||||
|  |  			default: | ||||||
|  |  				BUG(); | ||||||
|  |  			} | ||||||
|  | diff --git a/include/linux/if_team.h b/include/linux/if_team.h
 | ||||||
|  | index 6960fc1..33fcc20 100644
 | ||||||
|  | --- a/include/linux/if_team.h
 | ||||||
|  | +++ b/include/linux/if_team.h
 | ||||||
|  | @@ -67,6 +67,9 @@ struct team_port {
 | ||||||
|  |  	struct netpoll *np; | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +	s32 priority; /* lower number ~ higher priority */
 | ||||||
|  | +	u16 queue_id;
 | ||||||
|  | +	struct list_head qom_list; /* node in queue override mapping list */
 | ||||||
|  |  	long mode_priv[0]; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -130,6 +133,7 @@ enum team_option_type {
 | ||||||
|  |  	TEAM_OPTION_TYPE_STRING, | ||||||
|  |  	TEAM_OPTION_TYPE_BINARY, | ||||||
|  |  	TEAM_OPTION_TYPE_BOOL, | ||||||
|  | +	TEAM_OPTION_TYPE_S32,
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct team_option_inst_info { | ||||||
|  | @@ -146,6 +150,7 @@ struct team_gsetter_ctx {
 | ||||||
|  |  			u32 len; | ||||||
|  |  		} bin_val; | ||||||
|  |  		bool bool_val; | ||||||
|  | +		s32 s32_val;
 | ||||||
|  |  	} data; | ||||||
|  |  	struct team_option_inst_info *info; | ||||||
|  |  }; | ||||||
|  | @@ -197,6 +202,8 @@ struct team {
 | ||||||
|  |   | ||||||
|  |  	const struct team_mode *mode; | ||||||
|  |  	struct team_mode_ops ops; | ||||||
|  | +	bool queue_override_enabled;
 | ||||||
|  | +	struct list_head *qom_lists; /* array of queue override mapping lists */
 | ||||||
|  |  	long mode_priv[TEAM_MODE_PRIV_LONGS]; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | diff --git a/include/net/netlink.h b/include/net/netlink.h
 | ||||||
|  | index 785f37a..09175d5 100644
 | ||||||
|  | --- a/include/net/netlink.h
 | ||||||
|  | +++ b/include/net/netlink.h
 | ||||||
|  | @@ -98,6 +98,10 @@
 | ||||||
|  |   *   nla_put_u16(skb, type, value)	add u16 attribute to skb | ||||||
|  |   *   nla_put_u32(skb, type, value)	add u32 attribute to skb | ||||||
|  |   *   nla_put_u64(skb, type, value)	add u64 attribute to skb | ||||||
|  | + *   nla_put_s8(skb, type, value)	add s8 attribute to skb
 | ||||||
|  | + *   nla_put_s16(skb, type, value)	add s16 attribute to skb
 | ||||||
|  | + *   nla_put_s32(skb, type, value)	add s32 attribute to skb
 | ||||||
|  | + *   nla_put_s64(skb, type, value)	add s64 attribute to skb
 | ||||||
|  |   *   nla_put_string(skb, type, str)	add string attribute to skb | ||||||
|  |   *   nla_put_flag(skb, type)		add flag attribute to skb | ||||||
|  |   *   nla_put_msecs(skb, type, jiffies)	add msecs attribute to skb | ||||||
|  | @@ -121,6 +125,10 @@
 | ||||||
|  |   *   nla_get_u16(nla)			get payload for a u16 attribute | ||||||
|  |   *   nla_get_u32(nla)			get payload for a u32 attribute | ||||||
|  |   *   nla_get_u64(nla)			get payload for a u64 attribute | ||||||
|  | + *   nla_get_s8(nla)			get payload for a s8 attribute
 | ||||||
|  | + *   nla_get_s16(nla)			get payload for a s16 attribute
 | ||||||
|  | + *   nla_get_s32(nla)			get payload for a s32 attribute
 | ||||||
|  | + *   nla_get_s64(nla)			get payload for a s64 attribute
 | ||||||
|  |   *   nla_get_flag(nla)			return 1 if flag is true | ||||||
|  |   *   nla_get_msecs(nla)			get payload for a msecs attribute | ||||||
|  |   * | ||||||
|  | @@ -160,6 +168,10 @@ enum {
 | ||||||
|  |  	NLA_NESTED_COMPAT, | ||||||
|  |  	NLA_NUL_STRING, | ||||||
|  |  	NLA_BINARY, | ||||||
|  | +	NLA_S8,
 | ||||||
|  | +	NLA_S16,
 | ||||||
|  | +	NLA_S32,
 | ||||||
|  | +	NLA_S64,
 | ||||||
|  |  	__NLA_TYPE_MAX, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -183,6 +195,8 @@ enum {
 | ||||||
|  |   *    NLA_NESTED_COMPAT    Minimum length of structure payload | ||||||
|  |   *    NLA_U8, NLA_U16, | ||||||
|  |   *    NLA_U32, NLA_U64, | ||||||
|  | + *    NLA_S8, NLA_S16,
 | ||||||
|  | + *    NLA_S32, NLA_S64,
 | ||||||
|  |   *    NLA_MSECS            Leaving the length field zero will verify the | ||||||
|  |   *                         given type fits, using it verifies minimum length | ||||||
|  |   *                         just like "All other" | ||||||
|  | @@ -879,6 +893,50 @@ static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value)
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | + * nla_put_s8 - Add a s8 netlink attribute to a socket buffer
 | ||||||
|  | + * @skb: socket buffer to add attribute to
 | ||||||
|  | + * @attrtype: attribute type
 | ||||||
|  | + * @value: numeric value
 | ||||||
|  | + */
 | ||||||
|  | +static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value)
 | ||||||
|  | +{
 | ||||||
|  | +	return nla_put(skb, attrtype, sizeof(s8), &value);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  | + * nla_put_s16 - Add a s16 netlink attribute to a socket buffer
 | ||||||
|  | + * @skb: socket buffer to add attribute to
 | ||||||
|  | + * @attrtype: attribute type
 | ||||||
|  | + * @value: numeric value
 | ||||||
|  | + */
 | ||||||
|  | +static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value)
 | ||||||
|  | +{
 | ||||||
|  | +	return nla_put(skb, attrtype, sizeof(s16), &value);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  | + * nla_put_s32 - Add a s32 netlink attribute to a socket buffer
 | ||||||
|  | + * @skb: socket buffer to add attribute to
 | ||||||
|  | + * @attrtype: attribute type
 | ||||||
|  | + * @value: numeric value
 | ||||||
|  | + */
 | ||||||
|  | +static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value)
 | ||||||
|  | +{
 | ||||||
|  | +	return nla_put(skb, attrtype, sizeof(s32), &value);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  | + * nla_put_s64 - Add a s64 netlink attribute to a socket buffer
 | ||||||
|  | + * @skb: socket buffer to add attribute to
 | ||||||
|  | + * @attrtype: attribute type
 | ||||||
|  | + * @value: numeric value
 | ||||||
|  | + */
 | ||||||
|  | +static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value)
 | ||||||
|  | +{
 | ||||||
|  | +	return nla_put(skb, attrtype, sizeof(s64), &value);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  |   * nla_put_string - Add a string netlink attribute to a socket buffer | ||||||
|  |   * @skb: socket buffer to add attribute to | ||||||
|  |   * @attrtype: attribute type | ||||||
|  | @@ -994,6 +1052,46 @@ static inline __be64 nla_get_be64(const struct nlattr *nla)
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | + * nla_get_s32 - return payload of s32 attribute
 | ||||||
|  | + * @nla: s32 netlink attribute
 | ||||||
|  | + */
 | ||||||
|  | +static inline s32 nla_get_s32(const struct nlattr *nla)
 | ||||||
|  | +{
 | ||||||
|  | +	return *(s32 *) nla_data(nla);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  | + * nla_get_s16 - return payload of s16 attribute
 | ||||||
|  | + * @nla: s16 netlink attribute
 | ||||||
|  | + */
 | ||||||
|  | +static inline s16 nla_get_s16(const struct nlattr *nla)
 | ||||||
|  | +{
 | ||||||
|  | +	return *(s16 *) nla_data(nla);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  | + * nla_get_s8 - return payload of s8 attribute
 | ||||||
|  | + * @nla: s8 netlink attribute
 | ||||||
|  | + */
 | ||||||
|  | +static inline s8 nla_get_s8(const struct nlattr *nla)
 | ||||||
|  | +{
 | ||||||
|  | +	return *(s8 *) nla_data(nla);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  | + * nla_get_s64 - return payload of s64 attribute
 | ||||||
|  | + * @nla: s64 netlink attribute
 | ||||||
|  | + */
 | ||||||
|  | +static inline s64 nla_get_s64(const struct nlattr *nla)
 | ||||||
|  | +{
 | ||||||
|  | +	s64 tmp;
 | ||||||
|  | +
 | ||||||
|  | +	nla_memcpy(&tmp, nla, sizeof(tmp));
 | ||||||
|  | +
 | ||||||
|  | +	return tmp;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +/**
 | ||||||
|  |   * nla_get_flag - return payload of flag attribute | ||||||
|  |   * @nla: flag netlink attribute | ||||||
|  |   */ | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user