s390/net: updates 2017-12-20
Subsystems (4)
cover s390/net: updates 2017-12-20
Hi Dave,
Please apply the following patch series for 4.16.
Nothing too exciting, mostly just beating the qeth L3 code into shape.
Thanks & happy holidays,
Julian
Elena Reshetova (2):
net: convert lcs_reply.refcnt from atomic_t to refcount_t
qeth: convert qeth_reply.refcnt from atomic_t to refcount_t
Julian Wiedmann (13):
s390/qeth: use ip*_eth_mc_map helpers s390/qeth: drop CONFIG_QETH_IPV6
s390/qeth: don't keep track of MAC address's cast type s390/qeth: consolidate qeth MAC address helpers s390/qeth: use ether_addr_* helpers
s390/qeth: align L2 and L3 set_rx_mode() implementations s390/qeth: robustify qeth_get_ip_version() s390/qeth: clean up l3_get_cast_type() s390/qeth: recognize non-IP multicast on L3 transmit s390/qeth: unionize next-hop field in qeth L3 header s390/qeth: streamline l3_fill_header() s390/qeth: pass full data length to l3_fill_header() s390/qeth: replace open-coded in*_pton()
drivers/s390/net/Kconfig | 3 - drivers/s390/net/lcs.c | 10 +- drivers/s390/net/lcs.h | 3 +- drivers/s390/net/qeth_core.h | 42 ++-- drivers/s390/net/qeth_core_main.c | 19 +- drivers/s390/net/qeth_core_mpc.h | 13 +- drivers/s390/net/qeth_l2.h | 3 +- drivers/s390/net/qeth_l2_main.c | 92 +++----- drivers/s390/net/qeth_l3.h | 3 +- drivers/s390/net/qeth_l3_main.c | 474 +++++++++++--------------------------- drivers/s390/net/qeth_l3_sys.c | 12 + 11 files changed, 234 insertions(+), 440 deletions(-)
Signature · 1 line
2.13.5
PATCH 1/15 net: convert lcs_reply.refcnt from atomic_t to refcount_t
From: Elena Reshetova <[email protected]>
atomic_t variables are currently used to implement reference counters with the following properties:
- counter is initialized to 1 using atomic_set()
- a resource is freed upon counter reaching zero
- once counter reaches zero, its further increments aren't allowed
- counter schema uses basic atomic operations (set, inc, inc_not_zero, dec_and_test, etc.)
Such atomic variables should be converted to a newly provided refcount_t type and API that prevents accidental counter overflows and underflows. This is important since overflows and underflows can lead to use-after-free situation and be exploitable.
The variable lcs_reply.refcnt is used as pure reference counter. Convert it to refcount_t and fix up the operations.
--- drivers/s390/net/lcs.c | 10 +++------- drivers/s390/net/lcs.h | 3 ++- 2 files changed, 5 insertions(+), 8 deletions(-)
drivers/s390/net/lcs.c +3 -7
@@ -756,18 +756,14 @@ lcs_get_lancmd(struct lcs_card *card, int count)static void lcs_get_reply (struct lcs_reply *reply) { -WARN_ON (atomic_read (&reply->refcnt) <=0 ); -atomic_inc (&reply->refcnt); +refcount_inc (&reply->refcnt); }static void lcs_put_reply (struct lcs_reply *reply) { -WARN_ON (atomic_read (&reply->refcnt) <=0 ); -if (atomic_dec_and_test (&reply->refcnt)) { +if (refcount_dec_and_test (&reply->refcnt))kfree (reply); - } - } static struct lcs_reply *
@@ -780,7 +776,7 @@ lcs_alloc_reply(struct lcs_cmd *cmd) reply =kzalloc (sizeof (struct lcs_reply ),GFP_ATOMIC );if (!reply)return NULL ; -atomic_set (&reply->refcnt,1 ); +refcount_set (&reply->refcnt,1 ); reply->sequence_no = cmd->sequence_no; reply->received =0 ; reply->rc =0 ;
drivers/s390/net/lcs.h +2 -1
@@ -5,6 +5,7 @@#include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/workqueue.h> +#include <linux/refcount.h> #include <asm/ccwdev.h> #define LCS_DBF_TEXT (level, name, text) \
@@ -271,7 +272,7 @@ struct lcs_buffer {struct lcs_reply {struct list_head list;__u16 sequence_no; -atomic_t refcnt; +refcount_t refcnt;/* Callback for completion notification. */ void (*callback)(struct lcs_card *,struct lcs_cmd *);wait_queue_head_t wait_q;
Signature · 1 line
2.13.5
PATCH 2/15 qeth: convert qeth_reply.refcnt from atomic_t to refcount_t
In reply to Julian WiedmannFrom: Elena Reshetova <[email protected]>
atomic_t variables are currently used to implement reference counters with the following properties:
- counter is initialized to 1 using atomic_set()
- a resource is freed upon counter reaching zero
- once counter reaches zero, its further increments aren't allowed
- counter schema uses basic atomic operations (set, inc, inc_not_zero, dec_and_test, etc.)
Such atomic variables should be converted to a newly provided refcount_t type and API that prevents accidental counter overflows and underflows. This is important since overflows and underflows can lead to use-after-free situation and be exploitable.
The variable qeth_reply.refcnt is used as pure reference counter. Convert it to refcount_t and fix up the operations.
--- drivers/s390/net/qeth_core.h | 3 ++- drivers/s390/net/qeth_core_main.c | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-)
drivers/s390/net/qeth_core.h +2 -1
@@ -21,6 +21,7 @@#include <linux/ethtool.h> #include <linux/hashtable.h> #include <linux/ip.h> +#include <linux/refcount.h> #include <net/ipv6.h> #include <net/if_inet6.h>
@@ -632,7 +633,7 @@ struct qeth_reply {int rc;void *param;struct qeth_card *card; -atomic_t refcnt; +refcount_t refcnt; };struct qeth_card_blkt {
drivers/s390/net/qeth_core_main.c +3 -5
@@ -564,7 +564,7 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) reply =kzalloc (sizeof (struct qeth_reply ),GFP_ATOMIC );if (reply) { -atomic_set (&reply->refcnt,1 ); +refcount_set (&reply->refcnt,1 );atomic_set (&reply->received,0 ); reply->card = card; }
@@ -573,14 +573,12 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)static void qeth_get_reply (struct qeth_reply *reply) { -WARN_ON (atomic_read (&reply->refcnt) <=0 ); -atomic_inc (&reply->refcnt); +refcount_inc (&reply->refcnt); }static void qeth_put_reply (struct qeth_reply *reply) { -WARN_ON (atomic_read (&reply->refcnt) <=0 ); -if (atomic_dec_and_test (&reply->refcnt)) +if (refcount_dec_and_test (&reply->refcnt))kfree (reply); }
Signature · 1 line
2.13.5
PATCH 3/15 s390/qeth: use ip*_eth_mc_map helpers
In reply to Julian WiedmannGet rid of some wrapper indirection, and stop accessing the skb at hard-coded offsets.
--- drivers/s390/net/qeth_l3_main.c | 43 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 29 deletions(-)
drivers/s390/net/qeth_l3_main.c +14 -29
@@ -1328,11 +1328,6 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)return qeth_send_ipa_cmd (card, iob, qeth_diags_trace_cb,NULL ); } -static void qeth_l3_get_mac_for_ipm (__be32 ipm,char *mac) -{ -ip_eth_mc_map (ipm, mac); -} -static void qeth_l3_mark_all_mc_to_be_deleted (struct qeth_card *card) {struct qeth_ipaddr *addr;
@@ -1383,26 +1378,22 @@ static void qeth_l3_delete_nonused_mc(struct qeth_card *card) } -static void qeth_l3_add_mc_to_hash (struct qeth_card *card,struct in_device *in4_dev) {struct ip_mc_list *im4;struct qeth_ipaddr *tmp, *ipm; -char buf[MAX_ADDR_LEN ];QETH_CARD_TEXT (card,4 ,"addmc" ); tmp =qeth_l3_get_addr_buffer (QETH_PROT_IPV4 ); -if (!tmp) -return ; +if (!tmp) +return ;for (im4 =rcu_dereference (in4_dev->mc_list); im4 !=NULL ; im4 =rcu_dereference (im4->next_rcu)) { -qeth_l3_get_mac_for_ipm (im4->multiaddr, buf); - +ip_eth_mc_map (im4->multiaddr, tmp->mac); tmp->u.a4.addr =be32_to_cpu (im4->multiaddr); -memcpy (tmp->mac, buf,sizeof (tmp->mac)); tmp->is_multicast =1 ; ipm =qeth_l3_ip_from_hash (card, tmp);
@@ -1412,7 +1403,7 @@ qeth_l3_add_mc_to_hash(struct qeth_card *card, struct in_device *in4_dev) ipm =qeth_l3_get_addr_buffer (QETH_PROT_IPV4 );if (!ipm)continue ; -memcpy (ipm->mac, buf,sizeof (tmp->mac)); +memcpy (ipm->mac, tmp->mac,sizeof (tmp->mac)); ipm->u.a4.addr =be32_to_cpu (im4->multiaddr); ipm->is_multicast =1 ; ipm->disp_flag =QETH_DISP_ADDR_ADD ;
@@ -1473,18 +1464,15 @@ qeth_l3_add_mc6_to_hash(struct qeth_card *card, struct inet6_dev *in6_dev)struct qeth_ipaddr *ipm;struct ifmcaddr6 *im6;struct qeth_ipaddr *tmp; -char buf[MAX_ADDR_LEN ];QETH_CARD_TEXT (card,4 ,"addmc6" ); tmp =qeth_l3_get_addr_buffer (QETH_PROT_IPV6 ); -if (!tmp) -return ; +if (!tmp) +return ;for (im6 = in6_dev->mc_list; im6 !=NULL ; im6 = im6->next) { -ndisc_mc_map (&im6->mca_addr, buf, in6_dev->dev,0 ); - -memcpy (tmp->mac, buf,sizeof (tmp->mac)); +ipv6_eth_mc_map (&im6->mca_addr, tmp->mac);memcpy (&tmp->u.a6.addr, &im6->mca_addr.s6_addr,sizeof (struct in6_addr )); tmp->is_multicast =1 ;
@@ -1499,7 +1487,7 @@ qeth_l3_add_mc6_to_hash(struct qeth_card *card, struct inet6_dev *in6_dev)if (!ipm)continue ; -memcpy (ipm->mac, buf,OSA_ADDR_LEN ); +memcpy (ipm->mac, tmp->mac,sizeof (tmp->mac));memcpy (&ipm->u.a6.addr, &im6->mca_addr.s6_addr,sizeof (struct in6_addr )); ipm->is_multicast =1 ;
@@ -1679,26 +1667,23 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev,static void qeth_l3_rebuild_skb (struct qeth_card *card,struct sk_buff *skb,struct qeth_hdr *hdr) { -__u16 prot; -struct iphdr *ip_hdr;unsigned char tg_addr[MAX_ADDR_LEN ];if (!(hdr->hdr.l3.flags &QETH_HDR_PASSTHRU )) { - prot = (hdr->hdr.l3.flags &QETH_HDR_IPV6 ) ?ETH_P_IPV6 : -ETH_P_IP ; +u16 prot = (hdr->hdr.l3.flags &QETH_HDR_IPV6 ) ?ETH_P_IPV6 : +ETH_P_IP ; + +skb_reset_network_header (skb);switch (hdr->hdr.l3.flags &QETH_HDR_CAST_MASK ) {case QETH_CAST_MULTICAST :switch (prot) {#ifdef CONFIG_QETH_IPV6 case ETH_P_IPV6 : -ndisc_mc_map ((struct in6_addr *) - skb->data +24 , - tg_addr, card->dev,0 ); +ipv6_eth_mc_map (&ipv6_hdr (skb)->daddr, tg_addr);break ;#endif case ETH_P_IP : - ip_hdr = (struct iphdr *)skb->data; -ip_eth_mc_map (ip_hdr->daddr, tg_addr); +ip_eth_mc_map (ip_hdr (skb)->daddr, tg_addr);break ;default : memcpy(tg_addr, card->dev->broadcast,
Signature · 1 line
2.13.5
PATCH 4/15 s390/qeth: drop CONFIG_QETH_IPV6
In reply to Julian Wiedmanncommit "s390/qeth: use ip*_eth_mc_map helpers" removed the last occurrence of CONFIG_IPV6-dependent code.
--- drivers/s390/net/Kconfig | 3 --- drivers/s390/net/qeth_l3_main.c | 60 +++++++---------------------------------- 2 files changed, 9 insertions(+), 54 deletions(-)
drivers/s390/net/Kconfig +0 -3
@@ -91,9 +91,6 @@ config QETH_L3 To compile as a module choose M. The module name is qeth_l3. If unsure, choose Y. -config QETH_IPV6 - def_bool y if (QETH_L3 = IPV6) || (QETH_L3 && IPV6 = 'y') - config CCWGROUP tristate default (LCS || CTCM || QETH)
drivers/s390/net/qeth_l3_main.c +9 -51
190 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH 5/15 s390/qeth: don't keep track of MAC address's cast type
In reply to Julian WiedmannInstead of tracking the uc/mc state in each MAC address object, just check the multicast bit in the address itself.
--- drivers/s390/net/qeth_l2.h | 1 - drivers/s390/net/qeth_l2_main.c | 27 ++++++++------------------- 2 files changed, 8 insertions(+), 20 deletions(-)
drivers/s390/net/qeth_l2.h +0 -1
@@ -23,7 +23,6 @@ bool qeth_l2_vnicc_is_in_use(struct qeth_card *card);struct qeth_mac {u8 mac_addr[OSA_ADDR_LEN ]; -u8 is_uc:1 ;u8 disp_flag:2 ;struct hlist_node hnode; };
drivers/s390/net/qeth_l2_main.c +8 -19
@@ -186,22 +186,16 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)static int qeth_l2_write_mac (struct qeth_card *card,struct qeth_mac *mac) { -if (mac->is_uc) { -return qeth_l2_send_setdelmac (card, mac->mac_addr, -IPA_CMD_SETVMAC ); - }else { +if (is_multicast_ether_addr_64bits (mac->mac_addr))return qeth_l2_send_setgroupmac (card, mac->mac_addr); - } +return qeth_l2_send_setdelmac (card, mac->mac_addr,IPA_CMD_SETVMAC ); }static int qeth_l2_remove_mac (struct qeth_card *card,struct qeth_mac *mac) { -if (mac->is_uc) { -return qeth_l2_send_setdelmac (card, mac->mac_addr, -IPA_CMD_DELVMAC ); - }else { +if (is_multicast_ether_addr_64bits (mac->mac_addr))return qeth_l2_send_delgroupmac (card, mac->mac_addr); - } +return qeth_l2_send_setdelmac (card, mac->mac_addr,IPA_CMD_DELVMAC ); }static void qeth_l2_del_all_macs (struct qeth_card *card)
@@ -597,27 +591,23 @@ static void qeth_promisc_to_bridge(struct qeth_card *card)* only if there is not in the hash table storage already * */ -static void qeth_l2_add_mac (struct qeth_card *card,struct netdev_hw_addr *ha, -u8 is_uc) +static void qeth_l2_add_mac (struct qeth_card *card,struct netdev_hw_addr *ha) {u32 mac_hash =get_unaligned ((u32 *)(&ha->addr[2 ]));struct qeth_mac *mac;hash_for_each_possible (card->mac_htable, mac, hnode, mac_hash) { -if (is_uc == mac->is_uc && - !memcmp (ha->addr, mac->mac_addr,OSA_ADDR_LEN )) { +if (!memcmp (ha->addr, mac->mac_addr,OSA_ADDR_LEN )) { mac->disp_flag =QETH_DISP_ADDR_DO_NOTHING ;return ; } } mac =kzalloc (sizeof (struct qeth_mac ),GFP_ATOMIC ); -if (!mac)return ;memcpy (mac->mac_addr, ha->addr,OSA_ADDR_LEN ); - mac->is_uc = is_uc; mac->disp_flag =QETH_DISP_ADDR_ADD ;hash_add (card->mac_htable, &mac->hnode, mac_hash);
@@ -643,10 +633,9 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)spin_lock_bh (&card->mclock);netdev_for_each_mc_addr (ha, dev) -qeth_l2_add_mac (card, ha,0 ); - +qeth_l2_add_mac (card, ha);netdev_for_each_uc_addr (ha, dev) -qeth_l2_add_mac (card, ha,1 ); +qeth_l2_add_mac (card, ha);hash_for_each_safe (card->mac_htable, i, tmp, mac, hnode) {if (mac->disp_flag ==QETH_DISP_ADDR_DELETE ) {
Signature · 1 line
2.13.5
PATCH 6/15 s390/qeth: consolidate qeth MAC address helpers
In reply to Julian WiedmannFor adding/removing a MAC address, use just one helper each that handles both unicast and multicast.
Saves one level of indirection for multicast addresses, while improving the error reporting for unicast addresses.
--- drivers/s390/net/qeth_l2_main.c | 47 ++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 29 deletions(-)
drivers/s390/net/qeth_l2_main.c +18 -29
@@ -156,48 +156,37 @@ static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)return rc; } -static int qeth_l2_send_setgroupmac (struct qeth_card *card,__u8 *mac) +static int qeth_l2_write_mac (struct qeth_card *card,u8 *mac) { +enum qeth_ipa_cmds cmd =is_multicast_ether_addr_64bits (mac) ? +IPA_CMD_SETGMAC :IPA_CMD_SETVMAC ;int rc; -QETH_CARD_TEXT (card,2 ,"L2Sgmac" ); - rc =qeth_l2_send_setdelmac (card, mac,IPA_CMD_SETGMAC ); +QETH_CARD_TEXT (card,2 ,"L2Wmac" ); + rc =qeth_l2_send_setdelmac (card, mac, cmd);if (rc == -EEXIST ) -QETH_DBF_MESSAGE (2 ,"Group MAC %pM already existing on %s\n" , - mac,QETH_CARD_IFNAME (card)); +QETH_DBF_MESSAGE (2 ,"MAC %pM already registered on %s\n" , + mac,QETH_CARD_IFNAME (card));else if (rc) -QETH_DBF_MESSAGE (2 ,"Could not set group MAC %pM on %s: %d\n" , - mac,QETH_CARD_IFNAME (card), rc); +QETH_DBF_MESSAGE (2 ,"Failed to register MAC %pM on %s: %d\n" , + mac,QETH_CARD_IFNAME (card), rc);return rc; } -static int qeth_l2_send_delgroupmac (struct qeth_card *card,__u8 *mac) +static int qeth_l2_remove_mac (struct qeth_card *card,u8 *mac) { +enum qeth_ipa_cmds cmd =is_multicast_ether_addr_64bits (mac) ? +IPA_CMD_DELGMAC :IPA_CMD_DELVMAC ;int rc; -QETH_CARD_TEXT (card,2 ,"L2Dgmac" ); - rc =qeth_l2_send_setdelmac (card, mac,IPA_CMD_DELGMAC ); +QETH_CARD_TEXT (card,2 ,"L2Rmac" ); + rc =qeth_l2_send_setdelmac (card, mac, cmd);if (rc) -QETH_DBF_MESSAGE (2 , -"Could not delete group MAC %pM on %s: %d\n" , - mac,QETH_CARD_IFNAME (card), rc); +QETH_DBF_MESSAGE (2 ,"Failed to delete MAC %pM on %s: %d\n" , + mac,QETH_CARD_IFNAME (card), rc);return rc; } -static int qeth_l2_write_mac (struct qeth_card *card,struct qeth_mac *mac) -{ -if (is_multicast_ether_addr_64bits (mac->mac_addr)) -return qeth_l2_send_setgroupmac (card, mac->mac_addr); -return qeth_l2_send_setdelmac (card, mac->mac_addr,IPA_CMD_SETVMAC ); -} - -static int qeth_l2_remove_mac (struct qeth_card *card,struct qeth_mac *mac) -{ -if (is_multicast_ether_addr_64bits (mac->mac_addr)) -return qeth_l2_send_delgroupmac (card, mac->mac_addr); -return qeth_l2_send_setdelmac (card, mac->mac_addr,IPA_CMD_DELVMAC ); -} -static void qeth_l2_del_all_macs (struct qeth_card *card) {struct qeth_mac *mac;
@@ -639,12 +628,12 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)hash_for_each_safe (card->mac_htable, i, tmp, mac, hnode) {if (mac->disp_flag ==QETH_DISP_ADDR_DELETE ) { -qeth_l2_remove_mac (card, mac); +qeth_l2_remove_mac (card, mac->mac_addr);hash_del (&mac->hnode);kfree (mac); }else if (mac->disp_flag ==QETH_DISP_ADDR_ADD ) { - rc =qeth_l2_write_mac (card, mac); + rc =qeth_l2_write_mac (card, mac->mac_addr);if (rc) {hash_del (&mac->hnode);kfree (mac);
Signature · 1 line
2.13.5
PATCH 7/15 s390/qeth: use ether_addr_* helpers
In reply to Julian WiedmannBe a little more self-documenting, and get rid of OSA_ADDR_LEN.
--- drivers/s390/net/qeth_core_main.c | 11 +++++------ drivers/s390/net/qeth_core_mpc.h | 13 ++++++------- drivers/s390/net/qeth_l2.h | 2 +- drivers/s390/net/qeth_l2_main.c | 12 ++++++------ drivers/s390/net/qeth_l3.h | 2 +- drivers/s390/net/qeth_l3_main.c | 29 +++++++++++++---------------- 6 files changed, 32 insertions(+), 37 deletions(-)
drivers/s390/net/qeth_core_main.c +5 -6
@@ -4216,9 +4216,8 @@ static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data;if (!card->options.layer2 || !(card->info.mac_bits &QETH_LAYER2_MAC_READ )) { -memcpy (card->dev->dev_addr, - &cmd->data.setadapterparms.data.change_addr.addr, -OSA_ADDR_LEN ); +ether_addr_copy (card->dev->dev_addr, + cmd->data.setadapterparms.data.change_addr.addr); card->info.mac_bits |=QETH_LAYER2_MAC_READ ; }qeth_default_setadapterparms_cb (card, reply, (unsigned long ) cmd);
@@ -4240,9 +4239,9 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card)return -ENOMEM ; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE ); cmd->data.setadapterparms.data.change_addr.cmd =CHANGE_ADDR_READ_MAC ; - cmd->data.setadapterparms.data.change_addr.addr_size =OSA_ADDR_LEN ; -memcpy (&cmd->data.setadapterparms.data.change_addr.addr, - card->dev->dev_addr,OSA_ADDR_LEN ); + cmd->data.setadapterparms.data.change_addr.addr_size =ETH_ALEN ; +ether_addr_copy (cmd->data.setadapterparms.data.change_addr.addr, + card->dev->dev_addr); rc =qeth_send_ipa_cmd (card, iob, qeth_setadpparms_change_macaddr_cb,NULL );return rc;
drivers/s390/net/qeth_core_mpc.h +6 -7
@@ -10,6 +10,7 @@#define __QETH_CORE_MPC_H__#include <asm/qeth.h> +#include <uapi/linux/if_ether.h> #define IPA_PDU_HEADER_SIZE 0x40#define QETH_IPA_PDU_LEN_TOTAL (buffer) (buffer + 0x0e)
@@ -25,7 +26,6 @@ extern unsigned char IPA_PDU_HEADER[];#define QETH_SEQ_NO_LENGTH 4#define QETH_MPC_TOKEN_LENGTH 4#define QETH_MCL_LENGTH 4 -#define OSA_ADDR_LEN 6#define QETH_TIMEOUT (10 * HZ)#define QETH_IPA_TIMEOUT (45 * HZ)
@@ -416,12 +416,11 @@ struct qeth_query_cmds_supp { } __attribute__ ((packed));struct qeth_change_addr { -__u32 cmd; -__u32 addr_size; -__u32 no_macs; -__u8 addr[OSA_ADDR_LEN ]; -} __attribute__ ((packed)); - +u32 cmd; +u32 addr_size; +u32 no_macs; +u8 addr[ETH_ALEN ]; +};struct qeth_snmp_cmd {__u8 token[16 ];
drivers/s390/net/qeth_l2.h +1 -1
@@ -22,7 +22,7 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout);bool qeth_l2_vnicc_is_in_use (struct qeth_card *card);struct qeth_mac { -u8 mac_addr[OSA_ADDR_LEN ]; +u8 mac_addr[ETH_ALEN ];u8 disp_flag:2 ;struct hlist_node hnode; };
drivers/s390/net/qeth_l2_main.c +6 -6
@@ -109,8 +109,8 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,if (!iob)return -ENOMEM ; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE ); - cmd->data.setdelmac.mac_length =OSA_ADDR_LEN ; -memcpy (&cmd->data.setdelmac.mac, mac,OSA_ADDR_LEN ); + cmd->data.setdelmac.mac_length =ETH_ALEN ; +ether_addr_copy (cmd->data.setdelmac.mac, mac);return qeth_setdelmac_makerc (card,qeth_send_ipa_cmd (card, iob,NULL ,NULL )); }
@@ -123,7 +123,7 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) rc =qeth_l2_send_setdelmac (card, mac,IPA_CMD_SETVMAC );if (rc ==0 ) { card->info.mac_bits |=QETH_LAYER2_MAC_REGISTERED ; -memcpy (card->dev->dev_addr, mac,OSA_ADDR_LEN ); +ether_addr_copy (card->dev->dev_addr, mac);dev_info (&card->gdev->dev,"MAC address %pM successfully registered on device %s\n" , card->dev->dev_addr, card->dev->name);
@@ -532,7 +532,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)QETH_CARD_TEXT (card,3 ,"setmcTYP" );return -EOPNOTSUPP ; } -QETH_CARD_HEX (card,3 , addr->sa_data,OSA_ADDR_LEN ); +QETH_CARD_HEX (card,3 , addr->sa_data,ETH_ALEN );if (qeth_wait_for_threads (card,QETH_RECOVER_THREAD )) {QETH_CARD_TEXT (card,3 ,"setmcREC" );return -ERESTARTSYS ;
@@ -586,7 +586,7 @@ static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha)struct qeth_mac *mac;hash_for_each_possible (card->mac_htable, mac, hnode, mac_hash) { -if (!memcmp (ha->addr, mac->mac_addr,OSA_ADDR_LEN )) { +if (ether_addr_equal_64bits (ha->addr, mac->mac_addr)) { mac->disp_flag =QETH_DISP_ADDR_DO_NOTHING ;return ; }
@@ -596,7 +596,7 @@ static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha)if (!mac)return ; -memcpy (mac->mac_addr, ha->addr,OSA_ADDR_LEN ); +ether_addr_copy (mac->mac_addr, ha->addr); mac->disp_flag =QETH_DISP_ADDR_ADD ;hash_add (card->mac_htable, &mac->hnode, mac_hash);
drivers/s390/net/qeth_l3.h +1 -1
@@ -29,7 +29,7 @@ struct qeth_ipaddr {*/ int ref_counter;enum qeth_prot_versions proto; -unsigned char mac[OSA_ADDR_LEN ]; +unsigned char mac[ETH_ALEN ]; union { struct { unsigned int addr;
drivers/s390/net/qeth_l3_main.c +13 -16
@@ -207,8 +207,8 @@ inline int qeth_l3_ipaddrs_is_equal(struct qeth_ipaddr *addr1, struct qeth_ipaddr *addr2) { return addr1->proto == addr2->proto && - !memcmp(&addr1->u, &addr2->u, sizeof(addr1->u)) && - !memcmp(&addr1->mac, &addr2->mac, sizeof(addr1->mac)); + !memcmp(&addr1->u, &addr2->u, sizeof(addr1->u)) && + ether_addr_equal_64bits(addr1->mac, addr2->mac); } static struct qeth_ipaddr *
@@ -446,7 +446,7 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card,if (!iob)return -ENOMEM ; cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE ); -memcpy (&cmd->data.setdelipm.mac, addr->mac,OSA_ADDR_LEN ); +ether_addr_copy (cmd->data.setdelipm.mac, addr->mac);if (addr->proto ==QETH_PROT_IPV6 )memcpy (cmd->data.setdelipm.ip6, &addr->u.a6.addr,sizeof (struct in6_addr ));
@@ -1168,8 +1168,8 @@ static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data;if (cmd->hdr.return_code ==0 ) -memcpy (card->dev->dev_addr, - cmd->data.create_destroy_addr.unique_id,ETH_ALEN ); +ether_addr_copy (card->dev->dev_addr, + cmd->data.create_destroy_addr.unique_id);else eth_random_addr (card->dev->dev_addr);
@@ -1392,7 +1392,7 @@ qeth_l3_add_mc_to_hash(struct qeth_card *card, struct in_device *in4_dev) ipm =qeth_l3_get_addr_buffer (QETH_PROT_IPV4 );if (!ipm)continue ; -memcpy (ipm->mac, tmp->mac,sizeof (tmp->mac)); +ether_addr_copy (ipm->mac, tmp->mac); ipm->u.a4.addr =be32_to_cpu (im4->multiaddr); ipm->is_multicast =1 ; ipm->disp_flag =QETH_DISP_ADDR_ADD ;
@@ -1475,7 +1475,7 @@ static void qeth_l3_add_mc6_to_hash(struct qeth_card *card,if (!ipm)continue ; -memcpy (ipm->mac, tmp->mac,sizeof (tmp->mac)); +ether_addr_copy (ipm->mac, tmp->mac);memcpy (&ipm->u.a6.addr, &im6->mca_addr.s6_addr,sizeof (struct in6_addr )); ipm->is_multicast =1 ;
@@ -1652,11 +1652,10 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev,static void qeth_l3_rebuild_skb (struct qeth_card *card,struct sk_buff *skb,struct qeth_hdr *hdr) { -unsigned char tg_addr[MAX_ADDR_LEN ]; -if (!(hdr->hdr.l3.flags &QETH_HDR_PASSTHRU )) {u16 prot = (hdr->hdr.l3.flags &QETH_HDR_IPV6 ) ?ETH_P_IPV6 :ETH_P_IP ; +unsigned char tg_addr[ETH_ALEN ];skb_reset_network_header (skb);switch (hdr->hdr.l3.flags &QETH_HDR_CAST_MASK ) {
@@ -1670,8 +1669,7 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, skb->pkt_type =PACKET_MULTICAST ;break ;case QETH_CAST_BROADCAST : -memcpy (tg_addr, card->dev->broadcast, - card->dev->addr_len); +ether_addr_copy (tg_addr, card->dev->broadcast); card->stats.multicast++; skb->pkt_type =PACKET_BROADCAST ;break ;
@@ -1683,8 +1681,7 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, skb->pkt_type =PACKET_OTHERHOST ; else skb->pkt_type = PACKET_HOST; -memcpy (tg_addr, card->dev->dev_addr, - card->dev->addr_len); +ether_addr_copy (tg_addr, card->dev->dev_addr); }if (hdr->hdr.l3.ext_flags &QETH_HDR_EXT_SRC_MAC_ADDR ) card->dev->header_ops->create(skb, card->dev, prot,
@@ -2411,7 +2408,7 @@ static int qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)return ((skb_network_header (skb)[16 ] &0xf0 ) ==0xe0 ) ?RTN_MULTICAST :0 ;/* ... */ -if (!memcmp (skb->data, skb->dev->broadcast,6 )) +if (ether_addr_equal_64bits (eth_hdr (skb)->h_dest, skb->dev->broadcast))return RTN_BROADCAST ;else {u16 hdr_mac;
@@ -2504,8 +2501,8 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU ;memcpy (hdr->hdr.l3.dest_addr, pkey,16 ); }else { -if (!memcmp (skb->data +sizeof (struct qeth_hdr ), - skb->dev->broadcast,6 )) { +if (ether_addr_equal_64bits (eth_hdr (skb)->h_dest, + skb->dev->broadcast)) {/* broadcast? */ hdr->hdr.l3.flags =QETH_CAST_BROADCAST |QETH_HDR_PASSTHRU ;
Signature · 1 line
2.13.5
PATCH 8/15 s390/qeth: align L2 and L3 set_rx_mode() implementations
In reply to Julian WiedmannOnce all of qeth_l3_set_rx_mode()'s single-use helpers are folded back in, the two implementations actually look quite similar. So improve the readability by converting both set_rx_mode() routines to a common format.
This also allows us to walk ip_mc_htable just once, instead of three times.
--- drivers/s390/net/qeth_l2_main.c | 16 ++++--- drivers/s390/net/qeth_l3_main.c | 94 +++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 67 deletions(-)
drivers/s390/net/qeth_l2_main.c +10 -6
@@ -627,20 +627,24 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)qeth_l2_add_mac (card, ha);hash_for_each_safe (card->mac_htable, i, tmp, mac, hnode) { -if (mac->disp_flag ==QETH_DISP_ADDR_DELETE ) { +switch (mac->disp_flag) { +case QETH_DISP_ADDR_DELETE :qeth_l2_remove_mac (card, mac->mac_addr);hash_del (&mac->hnode);kfree (mac); - - }else if (mac->disp_flag ==QETH_DISP_ADDR_ADD ) { +break ; +case QETH_DISP_ADDR_ADD : rc =qeth_l2_write_mac (card, mac->mac_addr);if (rc) {hash_del (&mac->hnode);kfree (mac); - }else - mac->disp_flag =QETH_DISP_ADDR_DELETE ; - }else +break ; + } +/* fall through */ +default : +/* for next call to set_rx_mode(): */ mac->disp_flag =QETH_DISP_ADDR_DELETE ; + } }spin_unlock_bh (&card->mclock);
drivers/s390/net/qeth_l3_main.c +33 -61
148 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH 9/15 s390/qeth: robustify qeth_get_ip_version()
In reply to Julian WiedmannInstead of assuming that skb->data points to the Ethernet header, use the right helper and struct to access the Ethertype field.
--- drivers/s390/net/qeth_core.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/s390/net/qeth_core.h +8 -6
@@ -847,14 +847,16 @@ static inline int qeth_get_micros(void)static inline int qeth_get_ip_version (struct sk_buff *skb) { -__be16 *p = &((struct ethhdr *)skb->data)->h_proto; +struct vlan_ethhdr *veth =vlan_eth_hdr (skb); +__be16 prot = veth->h_vlan_proto; -if (be16_to_cpu (*p) ==ETH_P_8021Q ) - p +=2 ; -switch (be16_to_cpu (*p)) { -case ETH_P_IPV6 : +if (prot ==htons (ETH_P_8021Q )) + prot = veth->h_vlan_encapsulated_proto; + +switch (prot) { +case htons (ETH_P_IPV6 ):return 6 ; -case ETH_P_IP : +case htons (ETH_P_IP ):return 4 ;default :return 0 ;
Signature · 1 line
2.13.5
PATCH 10/15 s390/qeth: clean up l3_get_cast_type()
In reply to Julian WiedmannUse the proper helpers to check for multicast IP addressing, and remove some ancient Token Ring code.
--- drivers/s390/net/qeth_core.h | 3 --- drivers/s390/net/qeth_l3_main.c | 52 ++++++++++++++++------------------------- 2 files changed, 20 insertions(+), 35 deletions(-)
drivers/s390/net/qeth_core.h +0 -3
@@ -507,9 +507,6 @@ struct qeth_qdio_info {#define QETH_ETH_MAC_V4 0x0100/* like v4 */ #define QETH_ETH_MAC_V6 0x3333/* like v6 */ -/* tr mc mac is longer, but that will be enough to detect mc frames */ -#define QETH_TR_MAC_NC 0xc000/* non-canonical */ -#define QETH_TR_MAC_C 0x0300/* canonical */ /** * buffer stuff for read channel
drivers/s390/net/qeth_l3_main.c +20 -32
96 lines not on this page · raw message
Signature · 1 line
2.13.5
PATCH 11/15 s390/qeth: recognize non-IP multicast on L3 transmit
In reply to Julian WiedmannWhen
1. an skb has no neighbour, and
2. skb->protocol is not IP[V6],
we select the skb's cast type based on its destination MAC address.
The multicast check is currently restricted to Multicast IP-mapped MACs. Extend it to also cover non-IP Multicast MACs.
--- drivers/s390/net/qeth_core.h | 3 --- drivers/s390/net/qeth_l3_main.c | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-)
drivers/s390/net/qeth_core.h +0 -3
@@ -505,9 +505,6 @@ struct qeth_qdio_info {int default_out_queue; }; -#define QETH_ETH_MAC_V4 0x0100/* like v4 */ -#define QETH_ETH_MAC_V6 0x3333/* like v6 */ -/** * buffer stuff for read channel */
drivers/s390/net/qeth_l3_main.c +1 -2
@@ -2353,7 +2353,6 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)static int qeth_l3_get_cast_type (struct sk_buff *skb) { -u16 hdr_mac = *((u16 *)skb->data);struct neighbour *n =NULL ;struct dst_entry *dst;
@@ -2385,7 +2384,7 @@ static int qeth_l3_get_cast_type(struct sk_buff *skb)/* ... and MAC address */ if (ether_addr_equal_64bits (eth_hdr (skb)->h_dest, skb->dev->broadcast))return RTN_BROADCAST ; -if (hdr_mac ==QETH_ETH_MAC_V4 || hdr_mac ==QETH_ETH_MAC_V6 ) +if (is_multicast_ether_addr (eth_hdr (skb)->h_dest))return RTN_MULTICAST ;/* default to unicast */
Signature · 1 line
2.13.5
PATCH 12/15 s390/qeth: unionize next-hop field in qeth L3 header
In reply to Julian WiedmannThe L3 packet descriptor's 'dest_addr' field is used for a different purpose in RX descriptors. Clean up the hard-coded byte accesses and try to be more self-documenting.
--- drivers/s390/net/qeth_core.h | 19 +++++++++++++++++-- drivers/s390/net/qeth_l3_main.c | 12 ++++++------ 2 files changed, 23 insertions(+), 8 deletions(-)
drivers/s390/net/qeth_core.h +17 -2
@@ -297,8 +297,23 @@ struct qeth_hdr_layer3 {__u8 ext_flags;__u16 vlan_id;__u16 frame_offset; -__u8 dest_addr[16 ]; -} __attribute__ ((packed)); +union { +/* TX: */ +u8 ipv6_addr[16 ]; +struct ipv4 { +u8 res[12 ]; +u32 addr; + } ipv4; +/* RX: */ +struct rx { +u8 res1[2 ]; +u8 src_mac[6 ]; +u8 res2[4 ]; +u16 vlan_id; +u8 res3[2 ]; + } rx; + } next_hop; +};struct qeth_hdr_layer2 {__u8 id;
drivers/s390/net/qeth_l3_main.c +6 -6
@@ -1637,7 +1637,7 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, }if (hdr->hdr.l3.ext_flags &QETH_HDR_EXT_SRC_MAC_ADDR ) card->dev->header_ops->create (skb, card->dev, prot, - tg_addr, &hdr->hdr.l3.dest_addr[2 ], + tg_addr, &hdr->hdr.l3.next_hop.rx.src_mac, card->dev->addr_len);else card->dev->header_ops->create(skb, card->dev, prot,
@@ -1652,7 +1652,7 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, QETH_HDR_EXT_INCLUDE_VLAN_TAG))) {u16 tag = (hdr->hdr.l3.ext_flags &QETH_HDR_EXT_VLAN_FRAME ) ? hdr->hdr.l3.vlan_id : - *((u16 *)&hdr->hdr.l3.dest_addr[12 ]); + hdr->hdr.l3.next_hop.rx.vlan_id;__vlan_hwaccel_put_tag (skb,htons (ETH_P_8021Q ), tag); }
@@ -2408,7 +2408,7 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card, daddr[0 ] =0xfe ; daddr[1 ] =0x80 ;memcpy (&daddr[8 ], iucv_hdr->destUserID,8 ); -memcpy (hdr->hdr.l3.dest_addr, daddr,16 ); +memcpy (hdr->hdr.l3.next_hop.ipv6_addr, daddr,16 ); } static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
@@ -2445,8 +2445,8 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,/* IPv4 */ hdr->hdr.l3.flags =qeth_l3_get_qeth_hdr_flags4 (cast_type); -memset (hdr->hdr.l3.dest_addr,0 ,12 ); - *((__be32 *) (&hdr->hdr.l3.dest_addr[12 ])) = *pkey; +memset (hdr->hdr.l3.next_hop.ipv4.res,0 ,12 ); + *((__be32 *) &hdr->hdr.l3.next_hop.ipv4.addr) = *pkey; }else if (ipv ==6 ) {struct rt6_info *rt = (struct rt6_info *) dst;struct in6_addr *pkey = &ipv6_hdr (skb)->daddr;
@@ -2458,7 +2458,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.flags =qeth_l3_get_qeth_hdr_flags6 (cast_type);if (card->info.type ==QETH_CARD_TYPE_IQD ) hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU ; -memcpy (hdr->hdr.l3.dest_addr, pkey,16 ); +memcpy (hdr->hdr.l3.next_hop.ipv6_addr, pkey,16 ); }else {if (ether_addr_equal_64bits (eth_hdr (skb)->h_dest, skb->dev->broadcast)) {
Signature · 1 line
2.13.5
PATCH 13/15 s390/qeth: streamline l3_fill_header()
In reply to Julian WiedmannConsolidate the cast type translation, move the passthru path out of the RCU-guarded section, and use the appropriate rtable helpers when determining the next-hop address.
--- drivers/s390/net/qeth_l3_main.c | 99 ++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 56 deletions(-)
drivers/s390/net/qeth_l3_main.c +43 -56
@@ -23,12 +23,15 @@#include <linux/inetdevice.h> #include <linux/igmp.h> #include <linux/slab.h> +#include <linux/if_ether.h> #include <linux/if_vlan.h> +#include <linux/skbuff.h> #include <net/ip.h> #include <net/arp.h> #include <net/route.h> #include <net/ipv6.h> +#include <net/ip6_route.h> #include <net/ip6_fib.h> #include <net/ip6_checksum.h> #include <net/iucv/af_iucv.h>
@@ -896,27 +899,6 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card,return rc; } -static u8 qeth_l3_get_qeth_hdr_flags4 (int cast_type) -{ -if (cast_type ==RTN_MULTICAST ) -return QETH_CAST_MULTICAST ; -if (cast_type ==RTN_BROADCAST ) -return QETH_CAST_BROADCAST ; -return QETH_CAST_UNICAST ; -} - -static u8 qeth_l3_get_qeth_hdr_flags6 (int cast_type) -{ -u8 ct =QETH_HDR_PASSTHRU |QETH_HDR_IPV6 ; -if (cast_type ==RTN_MULTICAST ) -return ct |QETH_CAST_MULTICAST ; -if (cast_type ==RTN_ANYCAST ) -return ct |QETH_CAST_ANYCAST ; -if (cast_type ==RTN_BROADCAST ) -return ct |QETH_CAST_BROADCAST ; -return ct |QETH_CAST_UNICAST ; -} -static int qeth_l3_setadapter_parms (struct qeth_card *card) {int rc =0 ;
@@ -2411,14 +2393,23 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card,memcpy (hdr->hdr.l3.next_hop.ipv6_addr, daddr,16 ); } -static void qeth_l3_fill_header (struct qeth_card *card,struct qeth_hdr *hdr, -struct sk_buff *skb,int ipv,int cast_type) +static u8 qeth_l3_cast_type_to_flag (int cast_type) { -struct dst_entry *dst; +if (cast_type ==RTN_MULTICAST ) +return QETH_CAST_MULTICAST ; +if (cast_type ==RTN_ANYCAST ) +return QETH_CAST_ANYCAST ; +if (cast_type ==RTN_BROADCAST ) +return QETH_CAST_BROADCAST ; +return QETH_CAST_UNICAST ; +} +static void qeth_l3_fill_header (struct qeth_card *card,struct qeth_hdr *hdr, +struct sk_buff *skb,int ipv,int cast_type) +{memset (hdr,0 ,sizeof (struct qeth_hdr )); hdr->hdr.l3.id =QETH_HEADER_TYPE_LAYER3 ; - hdr->hdr.l3.ext_flags =0 ; + hdr->hdr.l3.length = skb->len -sizeof (struct qeth_hdr );/* * before we're going to overwrite this location with next hop ip.
@@ -2432,44 +2423,40 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.vlan_id =skb_vlan_tag_get (skb); } - hdr->hdr.l3.length = skb->len -sizeof (struct qeth_hdr ); +/* OSA only: */ +if (!ipv) { + hdr->hdr.l3.flags =QETH_HDR_PASSTHRU ; +if (ether_addr_equal_64bits (eth_hdr (skb)->h_dest, + skb->dev->broadcast)) + hdr->hdr.l3.flags |=QETH_CAST_BROADCAST ; +else + hdr->hdr.l3.flags |= (cast_type ==RTN_MULTICAST ) ? +QETH_CAST_MULTICAST :QETH_CAST_UNICAST ; +return ; + } + hdr->hdr.l3.flags =qeth_l3_cast_type_to_flag (cast_type);rcu_read_lock (); - dst =skb_dst (skb);if (ipv ==4 ) { -struct rtable *rt = (struct rtable *) dst; -__be32 *pkey = &ip_hdr (skb)->daddr; - -if (rt && rt->rt_gateway) - pkey = &rt->rt_gateway; +struct rtable *rt =skb_rtable (skb); -/* IPv4 */ - hdr->hdr.l3.flags =qeth_l3_get_qeth_hdr_flags4 (cast_type); -memset (hdr->hdr.l3.next_hop.ipv4.res,0 ,12 ); - *((__be32 *) &hdr->hdr.l3.next_hop.ipv4.addr) = *pkey; - }else if (ipv ==6 ) { -struct rt6_info *rt = (struct rt6_info *) dst; -struct in6_addr *pkey = &ipv6_hdr (skb)->daddr; + *((__be32 *) &hdr->hdr.l3.next_hop.ipv4.addr) = (rt) ? +rt_nexthop (rt,ip_hdr (skb)->daddr) : +ip_hdr (skb)->daddr; + }else { +/* IPv6 */ +const struct rt6_info *rt =skb_rt6_info (skb); +const struct in6_addr *next_hop;if (rt && !ipv6_addr_any (&rt->rt6i_gateway)) - pkey = &rt->rt6i_gateway; + next_hop = &rt->rt6i_gateway; +else + next_hop = &ipv6_hdr (skb)->daddr; +memcpy (hdr->hdr.l3.next_hop.ipv6_addr, next_hop,16 ); -/* IPv6 */ - hdr->hdr.l3.flags =qeth_l3_get_qeth_hdr_flags6 (cast_type); -if (card->info.type ==QETH_CARD_TYPE_IQD ) - hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU ; -memcpy (hdr->hdr.l3.next_hop.ipv6_addr, pkey,16 ); - }else { -if (ether_addr_equal_64bits (eth_hdr (skb)->h_dest, - skb->dev->broadcast)) { -/* broadcast? */ - hdr->hdr.l3.flags =QETH_CAST_BROADCAST | -QETH_HDR_PASSTHRU ; - }else { - hdr->hdr.l3.flags = (cast_type ==RTN_MULTICAST ) ? -QETH_CAST_MULTICAST |QETH_HDR_PASSTHRU : -QETH_CAST_UNICAST |QETH_HDR_PASSTHRU ; - } + hdr->hdr.l3.flags |=QETH_HDR_IPV6 ; +if (card->info.type !=QETH_CARD_TYPE_IQD ) + hdr->hdr.l3.flags |=QETH_HDR_PASSTHRU ; }rcu_read_unlock (); }
Signature · 1 line
2.13.5
PATCH 14/15 s390/qeth: pass full data length to l3_fill_header()
In reply to Julian WiedmannThe TSO and IQD paths already need to fix-up the current values, and OSA will require more flexibility in the future as well. So just let the caller specify the data length.
--- drivers/s390/net/qeth_l3_main.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/s390/net/qeth_l3_main.c +10 -8
@@ -2405,11 +2405,12 @@ static u8 qeth_l3_cast_type_to_flag(int cast_type) }static void qeth_l3_fill_header (struct qeth_card *card,struct qeth_hdr *hdr, -struct sk_buff *skb,int ipv,int cast_type) +struct sk_buff *skb,int ipv,int cast_type, +unsigned int data_len) {memset (hdr,0 ,sizeof (struct qeth_hdr )); hdr->hdr.l3.id =QETH_HEADER_TYPE_LAYER3 ; - hdr->hdr.l3.length = skb->len -sizeof (struct qeth_hdr ); + hdr->hdr.l3.length = data_len;/* * before we're going to overwrite this location with next hop ip.
@@ -2488,7 +2489,6 @@ static void qeth_tso_fill_header(struct qeth_card *card,/*fix header to TSO values ...*/ hdr->hdr.hdr.l3.id =QETH_HEADER_TYPE_TSO ; - hdr->hdr.hdr.l3.length = skb->len -sizeof (struct qeth_hdr_tso );/*set values which are fix for the first approach ...*/ hdr->ext.hdr_tot_len = (__u16 )sizeof (struct qeth_hdr_ext_tso ); hdr->ext.imb_hdr_no =1 ;
@@ -2649,21 +2649,23 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb,if (use_tso) { hdr =skb_push (new_skb,sizeof (struct qeth_hdr_tso ));memset (hdr,0 ,sizeof (struct qeth_hdr_tso )); -qeth_l3_fill_header (card, hdr, new_skb, ipv, cast_type); +qeth_l3_fill_header (card, hdr, new_skb, ipv, cast_type, + new_skb->len -sizeof (struct qeth_hdr_tso ));qeth_tso_fill_header (card, hdr, new_skb); hdr_elements++; }else {if (data_offset <0 ) { hdr =skb_push (new_skb,sizeof (struct qeth_hdr )); -qeth_l3_fill_header (card, hdr, new_skb, ipv, - cast_type); +qeth_l3_fill_header (card, hdr, new_skb, ipv, cast_type, + new_skb->len - +sizeof (struct qeth_hdr )); }else {if (be16_to_cpu (new_skb->protocol) ==ETH_P_AF_IUCV )qeth_l3_fill_af_iucv_hdr (card, hdr, new_skb);else {qeth_l3_fill_header (card, hdr, new_skb, ipv, - cast_type); - hdr->hdr.l3.length = new_skb->len - data_offset; + cast_type, + new_skb->len - data_offset); } }
Signature · 1 line
2.13.5
PATCH 15/15 s390/qeth: replace open-coded in*_pton()
In reply to Julian WiedmannThere's a common helper for parsing an IP address string, let's use it.
--- drivers/s390/net/qeth_l3.h | 1 - drivers/s390/net/qeth_l3_main.c | 88 ----------------------------------------- drivers/s390/net/qeth_l3_sys.c | 12 ++++++ 3 files changed, 12 insertions(+), 89 deletions(-)
drivers/s390/net/qeth_l3.h +0 -1
@@ -69,7 +69,6 @@ struct qeth_ipato_entry {extern const struct attribute_group *qeth_l3_attr_groups[];void qeth_l3_ipaddr_to_string (enum qeth_prot_versions ,const __u8 *,char *); -int qeth_l3_string_to_ipaddr (const char *,enum qeth_prot_versions ,__u8 *);int qeth_l3_create_device_attributes (struct device *);void qeth_l3_remove_device_attributes (struct device *);int qeth_l3_setrouting_v4 (struct qeth_card *);
drivers/s390/net/qeth_l3_main.c +0 -88
110 lines not on this page · raw message
drivers/s390/net/qeth_l3_sys.c +12 -0
@@ -10,11 +10,23 @@#include <linux/slab.h> #include <asm/ebcdic.h> #include <linux/hashtable.h> +#include <linux/inet.h> #include "qeth_l3.h" #define QETH_DEVICE_ATTR (_id, _name, _mode, _show, _store) \ struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store) +static int qeth_l3_string_to_ipaddr (const char *buf, +enum qeth_prot_versions proto,u8 *addr) +{ +const char *end; + +if ((proto ==QETH_PROT_IPV4 && !in4_pton (buf,-1 , addr,-1 , &end)) || + (proto ==QETH_PROT_IPV6 && !in6_pton (buf,-1 , addr,-1 , &end))) +return -EINVAL ; +return 0 ; +} +static ssize_t qeth_l3_dev_route_show (struct qeth_card *card,struct qeth_routing_info *route,char *buf) {
Signature · 1 line
2.13.5
David Miller
maintainerFrom: Julian Wiedmann <[email protected]>
Date: Wed, 20 Dec 2017 20:10:54 +0100
Quoted 2 lines
Please apply the following patch series for 4.16.
Nothing too exciting, mostly just beating the qeth L3 code into shape.
Series applied, thanks.
Quoted 2 lines
Thanks & happy holidays,
Julian
Same to you!