Skip to content

Commit b5dbc85

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: rtnetlink: make SR-IOV VF interface symmetric sctp: delete active ICMP proto unreachable timer when free transport tcp: fix MD5 (RFC2385) support
2 parents d34e14f + c02db8c commit b5dbc85

File tree

5 files changed

+160
-81
lines changed

5 files changed

+160
-81
lines changed

include/linux/if_link.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,7 @@ enum {
7979
IFLA_NET_NS_PID,
8080
IFLA_IFALIAS,
8181
IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */
82-
IFLA_VF_MAC, /* Hardware queue specific attributes */
83-
IFLA_VF_VLAN,
84-
IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
85-
IFLA_VFINFO,
82+
IFLA_VFINFO_LIST,
8683
__IFLA_MAX
8784
};
8885

@@ -203,6 +200,24 @@ enum macvlan_mode {
203200

204201
/* SR-IOV virtual function managment section */
205202

203+
enum {
204+
IFLA_VF_INFO_UNSPEC,
205+
IFLA_VF_INFO,
206+
__IFLA_VF_INFO_MAX,
207+
};
208+
209+
#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
210+
211+
enum {
212+
IFLA_VF_UNSPEC,
213+
IFLA_VF_MAC, /* Hardware queue specific attributes */
214+
IFLA_VF_VLAN,
215+
IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
216+
__IFLA_VF_MAX,
217+
};
218+
219+
#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
220+
206221
struct ifla_vf_mac {
207222
__u32 vf;
208223
__u8 mac[32]; /* MAX_ADDR_LEN */

include/net/tcp.h

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,30 +1197,15 @@ extern int tcp_v4_md5_do_del(struct sock *sk,
11971197
extern struct tcp_md5sig_pool * __percpu *tcp_alloc_md5sig_pool(struct sock *);
11981198
extern void tcp_free_md5sig_pool(void);
11991199

1200-
extern struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu);
1201-
extern void __tcp_put_md5sig_pool(void);
1200+
extern struct tcp_md5sig_pool *tcp_get_md5sig_pool(void);
1201+
extern void tcp_put_md5sig_pool(void);
1202+
12021203
extern int tcp_md5_hash_header(struct tcp_md5sig_pool *, struct tcphdr *);
12031204
extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, struct sk_buff *,
12041205
unsigned header_len);
12051206
extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp,
12061207
struct tcp_md5sig_key *key);
12071208

1208-
static inline
1209-
struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
1210-
{
1211-
int cpu = get_cpu();
1212-
struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu);
1213-
if (!ret)
1214-
put_cpu();
1215-
return ret;
1216-
}
1217-
1218-
static inline void tcp_put_md5sig_pool(void)
1219-
{
1220-
__tcp_put_md5sig_pool();
1221-
put_cpu();
1222-
}
1223-
12241209
/* write queue abstraction */
12251210
static inline void tcp_write_queue_purge(struct sock *sk)
12261211
{

net/core/rtnetlink.c

Lines changed: 110 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -602,12 +602,19 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
602602
a->tx_compressed = b->tx_compressed;
603603
};
604604

605+
/* All VF info */
605606
static inline int rtnl_vfinfo_size(const struct net_device *dev)
606607
{
607-
if (dev->dev.parent && dev_is_pci(dev->dev.parent))
608-
return dev_num_vf(dev->dev.parent) *
609-
sizeof(struct ifla_vf_info);
610-
else
608+
if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
609+
610+
int num_vfs = dev_num_vf(dev->dev.parent);
611+
size_t size = nlmsg_total_size(sizeof(struct nlattr));
612+
size += nlmsg_total_size(num_vfs * sizeof(struct nlattr));
613+
size += num_vfs * (sizeof(struct ifla_vf_mac) +
614+
sizeof(struct ifla_vf_vlan) +
615+
sizeof(struct ifla_vf_tx_rate));
616+
return size;
617+
} else
611618
return 0;
612619
}
613620

@@ -629,7 +636,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
629636
+ nla_total_size(1) /* IFLA_OPERSTATE */
630637
+ nla_total_size(1) /* IFLA_LINKMODE */
631638
+ nla_total_size(4) /* IFLA_NUM_VF */
632-
+ nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */
639+
+ rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
633640
+ rtnl_link_get_size(dev); /* IFLA_LINKINFO */
634641
}
635642

@@ -700,14 +707,37 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
700707

701708
if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
702709
int i;
703-
struct ifla_vf_info ivi;
704710

705-
NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
706-
for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
711+
struct nlattr *vfinfo, *vf;
712+
int num_vfs = dev_num_vf(dev->dev.parent);
713+
714+
NLA_PUT_U32(skb, IFLA_NUM_VF, num_vfs);
715+
vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
716+
if (!vfinfo)
717+
goto nla_put_failure;
718+
for (i = 0; i < num_vfs; i++) {
719+
struct ifla_vf_info ivi;
720+
struct ifla_vf_mac vf_mac;
721+
struct ifla_vf_vlan vf_vlan;
722+
struct ifla_vf_tx_rate vf_tx_rate;
707723
if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
708724
break;
709-
NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi);
725+
vf_mac.vf = vf_vlan.vf = vf_tx_rate.vf = ivi.vf;
726+
memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
727+
vf_vlan.vlan = ivi.vlan;
728+
vf_vlan.qos = ivi.qos;
729+
vf_tx_rate.rate = ivi.tx_rate;
730+
vf = nla_nest_start(skb, IFLA_VF_INFO);
731+
if (!vf) {
732+
nla_nest_cancel(skb, vfinfo);
733+
goto nla_put_failure;
734+
}
735+
NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
736+
NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan);
737+
NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), &vf_tx_rate);
738+
nla_nest_end(skb, vf);
710739
}
740+
nla_nest_end(skb, vfinfo);
711741
}
712742
if (dev->rtnl_link_ops) {
713743
if (rtnl_link_fill(skb, dev) < 0)
@@ -769,12 +799,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
769799
[IFLA_LINKINFO] = { .type = NLA_NESTED },
770800
[IFLA_NET_NS_PID] = { .type = NLA_U32 },
771801
[IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
772-
[IFLA_VF_MAC] = { .type = NLA_BINARY,
773-
.len = sizeof(struct ifla_vf_mac) },
774-
[IFLA_VF_VLAN] = { .type = NLA_BINARY,
775-
.len = sizeof(struct ifla_vf_vlan) },
776-
[IFLA_VF_TX_RATE] = { .type = NLA_BINARY,
777-
.len = sizeof(struct ifla_vf_tx_rate) },
802+
[IFLA_VFINFO_LIST] = {. type = NLA_NESTED },
778803
};
779804
EXPORT_SYMBOL(ifla_policy);
780805

@@ -783,6 +808,19 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
783808
[IFLA_INFO_DATA] = { .type = NLA_NESTED },
784809
};
785810

811+
static const struct nla_policy ifla_vfinfo_policy[IFLA_VF_INFO_MAX+1] = {
812+
[IFLA_VF_INFO] = { .type = NLA_NESTED },
813+
};
814+
815+
static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
816+
[IFLA_VF_MAC] = { .type = NLA_BINARY,
817+
.len = sizeof(struct ifla_vf_mac) },
818+
[IFLA_VF_VLAN] = { .type = NLA_BINARY,
819+
.len = sizeof(struct ifla_vf_vlan) },
820+
[IFLA_VF_TX_RATE] = { .type = NLA_BINARY,
821+
.len = sizeof(struct ifla_vf_tx_rate) },
822+
};
823+
786824
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
787825
{
788826
struct net *net;
@@ -812,6 +850,52 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
812850
return 0;
813851
}
814852

853+
static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
854+
{
855+
int rem, err = -EINVAL;
856+
struct nlattr *vf;
857+
const struct net_device_ops *ops = dev->netdev_ops;
858+
859+
nla_for_each_nested(vf, attr, rem) {
860+
switch (nla_type(vf)) {
861+
case IFLA_VF_MAC: {
862+
struct ifla_vf_mac *ivm;
863+
ivm = nla_data(vf);
864+
err = -EOPNOTSUPP;
865+
if (ops->ndo_set_vf_mac)
866+
err = ops->ndo_set_vf_mac(dev, ivm->vf,
867+
ivm->mac);
868+
break;
869+
}
870+
case IFLA_VF_VLAN: {
871+
struct ifla_vf_vlan *ivv;
872+
ivv = nla_data(vf);
873+
err = -EOPNOTSUPP;
874+
if (ops->ndo_set_vf_vlan)
875+
err = ops->ndo_set_vf_vlan(dev, ivv->vf,
876+
ivv->vlan,
877+
ivv->qos);
878+
break;
879+
}
880+
case IFLA_VF_TX_RATE: {
881+
struct ifla_vf_tx_rate *ivt;
882+
ivt = nla_data(vf);
883+
err = -EOPNOTSUPP;
884+
if (ops->ndo_set_vf_tx_rate)
885+
err = ops->ndo_set_vf_tx_rate(dev, ivt->vf,
886+
ivt->rate);
887+
break;
888+
}
889+
default:
890+
err = -EINVAL;
891+
break;
892+
}
893+
if (err)
894+
break;
895+
}
896+
return err;
897+
}
898+
815899
static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
816900
struct nlattr **tb, char *ifname, int modified)
817901
{
@@ -942,40 +1026,17 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
9421026
write_unlock_bh(&dev_base_lock);
9431027
}
9441028

945-
if (tb[IFLA_VF_MAC]) {
946-
struct ifla_vf_mac *ivm;
947-
ivm = nla_data(tb[IFLA_VF_MAC]);
948-
err = -EOPNOTSUPP;
949-
if (ops->ndo_set_vf_mac)
950-
err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac);
951-
if (err < 0)
952-
goto errout;
953-
modified = 1;
954-
}
955-
956-
if (tb[IFLA_VF_VLAN]) {
957-
struct ifla_vf_vlan *ivv;
958-
ivv = nla_data(tb[IFLA_VF_VLAN]);
959-
err = -EOPNOTSUPP;
960-
if (ops->ndo_set_vf_vlan)
961-
err = ops->ndo_set_vf_vlan(dev, ivv->vf,
962-
ivv->vlan,
963-
ivv->qos);
964-
if (err < 0)
965-
goto errout;
966-
modified = 1;
967-
}
968-
err = 0;
969-
970-
if (tb[IFLA_VF_TX_RATE]) {
971-
struct ifla_vf_tx_rate *ivt;
972-
ivt = nla_data(tb[IFLA_VF_TX_RATE]);
973-
err = -EOPNOTSUPP;
974-
if (ops->ndo_set_vf_tx_rate)
975-
err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate);
976-
if (err < 0)
977-
goto errout;
978-
modified = 1;
1029+
if (tb[IFLA_VFINFO_LIST]) {
1030+
struct nlattr *attr;
1031+
int rem;
1032+
nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) {
1033+
if (nla_type(attr) != IFLA_VF_INFO)
1034+
goto errout;
1035+
err = do_setvfinfo(dev, attr);
1036+
if (err < 0)
1037+
goto errout;
1038+
modified = 1;
1039+
}
9791040
}
9801041
err = 0;
9811042

net/ipv4/tcp.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,7 +2839,6 @@ static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool * __percpu *pool)
28392839
if (p->md5_desc.tfm)
28402840
crypto_free_hash(p->md5_desc.tfm);
28412841
kfree(p);
2842-
p = NULL;
28432842
}
28442843
}
28452844
free_percpu(pool);
@@ -2937,25 +2936,40 @@ struct tcp_md5sig_pool * __percpu *tcp_alloc_md5sig_pool(struct sock *sk)
29372936

29382937
EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
29392938

2940-
struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu)
2939+
2940+
/**
2941+
* tcp_get_md5sig_pool - get md5sig_pool for this user
2942+
*
2943+
* We use percpu structure, so if we succeed, we exit with preemption
2944+
* and BH disabled, to make sure another thread or softirq handling
2945+
* wont try to get same context.
2946+
*/
2947+
struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
29412948
{
29422949
struct tcp_md5sig_pool * __percpu *p;
2943-
spin_lock_bh(&tcp_md5sig_pool_lock);
2950+
2951+
local_bh_disable();
2952+
2953+
spin_lock(&tcp_md5sig_pool_lock);
29442954
p = tcp_md5sig_pool;
29452955
if (p)
29462956
tcp_md5sig_users++;
2947-
spin_unlock_bh(&tcp_md5sig_pool_lock);
2948-
return (p ? *per_cpu_ptr(p, cpu) : NULL);
2949-
}
2957+
spin_unlock(&tcp_md5sig_pool_lock);
2958+
2959+
if (p)
2960+
return *per_cpu_ptr(p, smp_processor_id());
29502961

2951-
EXPORT_SYMBOL(__tcp_get_md5sig_pool);
2962+
local_bh_enable();
2963+
return NULL;
2964+
}
2965+
EXPORT_SYMBOL(tcp_get_md5sig_pool);
29522966

2953-
void __tcp_put_md5sig_pool(void)
2967+
void tcp_put_md5sig_pool(void)
29542968
{
2969+
local_bh_enable();
29552970
tcp_free_md5sig_pool();
29562971
}
2957-
2958-
EXPORT_SYMBOL(__tcp_put_md5sig_pool);
2972+
EXPORT_SYMBOL(tcp_put_md5sig_pool);
29592973

29602974
int tcp_md5_hash_header(struct tcp_md5sig_pool *hp,
29612975
struct tcphdr *th)

net/sctp/transport.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ void sctp_transport_free(struct sctp_transport *transport)
173173
del_timer(&transport->T3_rtx_timer))
174174
sctp_transport_put(transport);
175175

176+
/* Delete the ICMP proto unreachable timer if it's active. */
177+
if (timer_pending(&transport->proto_unreach_timer) &&
178+
del_timer(&transport->proto_unreach_timer))
179+
sctp_association_put(transport->asoc);
176180

177181
sctp_transport_put(transport);
178182
}

0 commit comments

Comments
 (0)