[NET]: Wrap netdevice hardware header creation.

Add inline for common usage of hardware header creation, and
fix bug in IPV6 mcast where the assumption about negative return is
an errno. Negative return from hard_header means not enough space
was available,(ie -N bytes).

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Stephen Hemminger 2007-10-09 01:36:32 -07:00 committed by David S. Miller
parent 4c94f8c0c9
commit 0c4e85813d
19 changed files with 63 additions and 70 deletions

View File

@ -286,7 +286,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
skb->protocol = ax25_type_trans(skb, dev);
skb_reset_network_header(skb);
dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
bpq->stats.tx_packets++;
bpq->stats.tx_bytes+=skb->len;

View File

@ -170,7 +170,7 @@ static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
const struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
return lowerdev->hard_header(skb, lowerdev, type, daddr,
return dev_hard_header(skb, lowerdev, type, daddr,
saddr ? : dev->dev_addr, len);
}

View File

@ -834,7 +834,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
}
error = total_len;
dev->hard_header(skb, dev, ETH_P_PPP_SES,
dev_hard_header(skb, dev, ETH_P_PPP_SES,
po->pppoe_pa.remote, NULL, total_len);
memcpy(ph, &hdr, sizeof(struct pppoe_hdr));
@ -886,7 +886,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
skb->protocol = __constant_htons(ETH_P_PPP_SES);
skb->dev = dev;
dev->hard_header(skb, dev, ETH_P_PPP_SES,
dev_hard_header(skb, dev, ETH_P_PPP_SES,
po->pppoe_pa.remote, NULL, data_len);
dev_queue_xmit(skb);

View File

@ -216,7 +216,7 @@ static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb)
skb->dev = dev = lapbeth->ethdev;
dev->hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0);
dev_hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0);
dev_queue_xmit(skb);
}

View File

@ -800,6 +800,15 @@ extern int dev_restart(struct net_device *dev);
extern int netpoll_trap(void);
#endif
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type,
void *daddr, void *saddr, unsigned len)
{
if (!dev->hard_header)
return 0;
return dev->hard_header(skb, dev, type, daddr, saddr, len);
}
typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf);
static inline int unregister_gifconf(unsigned int family)

View File

@ -100,8 +100,7 @@ static inline void dn_rt_finish_output(struct sk_buff *skb, char *dst, char *src
if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK))
dst = NULL;
if (!dev->hard_header || (dev->hard_header(skb, dev, ETH_P_DNA_RT,
dst, src, skb->len) >= 0))
if (dev_hard_header(skb, dev, ETH_P_DNA_RT, dst, src, skb->len) >= 0)
dn_rt_send(skb);
else
kfree_skb(skb);

View File

@ -31,7 +31,7 @@ static int p8023_request(struct datalink_proto *dl,
{
struct net_device *dev = skb->dev;
dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
dev_hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
return dev_queue_xmit(skb);
}

View File

@ -434,21 +434,19 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
if (build_vlan_header) {
/* Now make the underlying real hard header */
rc = dev->hard_header(skb, dev, ETH_P_8021Q, daddr, saddr, len + VLAN_HLEN);
if (rc > 0) {
rc = dev_hard_header(skb, dev, ETH_P_8021Q, daddr, saddr,
len + VLAN_HLEN);
if (rc > 0)
rc += VLAN_HLEN;
} else if (rc < 0) {
else if (rc < 0)
rc -= VLAN_HLEN;
}
} else {
} else
/* If here, then we'll just make a normal looking ethernet frame,
* but, the hard_start_xmit method will insert the tag (it has to
* be able to do this for bridged and other skbs that don't come
* down the protocol stack in an orderly manner.
*/
rc = dev->hard_header(skb, dev, type, daddr, saddr, len);
}
rc = dev_hard_header(skb, dev, type, daddr, saddr, len);
return rc;
}

View File

@ -1125,8 +1125,7 @@ int neigh_compat_output(struct sk_buff *skb)
__skb_pull(skb, skb_network_offset(skb));
if (dev->hard_header &&
dev->hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL,
if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL,
skb->len) < 0 &&
dev->rebuild_header(skb))
return 0;
@ -1154,12 +1153,12 @@ int neigh_resolve_output(struct sk_buff *skb)
write_lock_bh(&neigh->lock);
if (!dst->hh)
neigh_hh_init(neigh, dst, dst->ops->protocol);
err = dev->hard_header(skb, dev, ntohs(skb->protocol),
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
neigh->ha, NULL, skb->len);
write_unlock_bh(&neigh->lock);
} else {
read_lock_bh(&neigh->lock);
err = dev->hard_header(skb, dev, ntohs(skb->protocol),
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
neigh->ha, NULL, skb->len);
read_unlock_bh(&neigh->lock);
}
@ -1191,7 +1190,7 @@ int neigh_connected_output(struct sk_buff *skb)
__skb_pull(skb, skb_network_offset(skb));
read_lock_bh(&neigh->lock);
err = dev->hard_header(skb, dev, ntohs(skb->protocol),
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
neigh->ha, NULL, skb->len);
read_unlock_bh(&neigh->lock);
if (err >= 0)

View File

@ -415,9 +415,7 @@ static void arp_reply(struct sk_buff *skb)
send_skb->protocol = htons(ETH_P_ARP);
/* Fill the device header for the ARP frame */
if (np->dev->hard_header &&
np->dev->hard_header(send_skb, skb->dev, ptype,
if (dev_hard_header(send_skb, skb->dev, ptype,
sha, np->local_mac,
send_skb->len) < 0) {
kfree_skb(send_skb);

View File

@ -211,7 +211,8 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
char mac_addr[ETH_ALEN];
dn_dn2eth(mac_addr, rt->rt_local_src);
if (!dev->hard_header || dev->hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, mac_addr, skb->len) >= 0)
if (dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha,
mac_addr, skb->len) >= 0)
return neigh->ops->queue_xmit(skb);
if (net_ratelimit())

View File

@ -336,6 +336,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
/* Real hardware Econet. We're not worthy etc. */
#ifdef CONFIG_ECONET_NATIVE
unsigned short proto = 0;
int res;
dev_hold(dev);
@ -354,12 +355,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
eb->sec = *saddr;
eb->sent = ec_tx_done;
if (dev->hard_header) {
int res;
struct ec_framehdr *fh;
err = -EINVAL;
res = dev->hard_header(skb, dev, ntohs(proto),
&addr, NULL, len);
res = dev_hard_header(skb, dev, ntohs(proto), &addr, NULL, len);
if (res < 0)
goto out_free;
if (res > 0) {
struct ec_framehdr *fh;
/* Poke in our control byte and
port number. Hack, hack. */
fh = (struct ec_framehdr *)(skb->data);
@ -368,8 +369,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
if (sock->type != SOCK_DGRAM) {
skb_reset_tail_pointer(skb);
skb->len = 0;
} else if (res < 0)
goto out_free;
}
}
/* Copy the data. Returns -EFAULT on error */

View File

@ -12,9 +12,7 @@ static int pEII_request(struct datalink_proto *dl,
struct net_device *dev = skb->dev;
skb->protocol = htons(ETH_P_IPX);
if (dev->hard_header)
dev->hard_header(skb, dev, ETH_P_IPX,
dest_node, NULL, skb->len);
dev_hard_header(skb, dev, ETH_P_IPX, dest_node, NULL, skb->len);
return dev_queue_xmit(skb);
}

View File

@ -591,8 +591,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
/*
* Fill the device header for the ARP frame
*/
if (dev->hard_header &&
dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len) < 0)
if (dev_hard_header(skb, dev, ptype, dest_hw, src_hw, skb->len) < 0)
goto out;
/*

View File

@ -757,8 +757,8 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
/* Chain packet down the line... */
skb->dev = dev;
skb->protocol = htons(ETH_P_IP);
if ((dev->hard_header &&
dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||
if (dev_hard_header(skb, dev, ntohs(skb->protocol),
dev->broadcast, dev->dev_addr, skb->len) < 0 ||
dev_queue_xmit(skb) < 0)
printk("E");
}

View File

@ -1438,17 +1438,12 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
if (dev->hard_header) {
unsigned char ha[MAX_ADDR_LEN];
int err;
ndisc_mc_map(&ipv6_hdr(skb)->daddr, ha, dev, 1);
err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len);
if (err < 0) {
if (dev_hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len) < 0) {
kfree_skb(skb);
return err;
}
return -EINVAL;
}
return dev_queue_xmit(skb);
}

View File

@ -765,16 +765,10 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb_reset_network_header(skb);
if (dev->hard_header) {
int res;
err = -EINVAL;
res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);
if (sock->type != SOCK_DGRAM) {
skb_reset_tail_pointer(skb);
skb->len = 0;
} else if (res < 0)
if (sock->type == SOCK_DGRAM &&
dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len) < 0)
goto out_free;
}
/* Returns -EFAULT on error */
err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);

View File

@ -232,9 +232,12 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
}
if (neigh_event_send(n, skb_res) == 0) {
int err;
read_lock(&n->lock);
err = dev->hard_header(skb, dev, ntohs(skb->protocol), n->ha, NULL, skb->len);
err = dev_hard_header(skb, dev, ntohs(skb->protocol),
n->ha, NULL, skb->len);
read_unlock(&n->lock);
if (err < 0) {
neigh_release(n);
return -EINVAL;

View File

@ -77,7 +77,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
skb_reset_network_header(clone);
dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev;
clone->dev = dev;
dev->hard_header(clone, dev, ETH_P_TIPC,
dev_hard_header(clone, dev, ETH_P_TIPC,
&dest->dev_addr.eth_addr,
dev->dev_addr, clone->len);
dev_queue_xmit(clone);