X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fllc%2Fllc_sap.c;h=008de1fc42ca79b07cafed68ccb3e7e396161dc9;hb=0b15a3a5285bac2a2caa4ef970410674b6dd2de5;hp=61cb8cf7d1532a4d4b1abd51244e863fc7e8b887;hpb=7ee66fcb94cb8be77d5f34cce7d315d11759f9c1;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 61cb8cf..008de1f 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -24,23 +24,45 @@ #include #include +static int llc_mac_header_len(unsigned short devtype) +{ + switch (devtype) { + case ARPHRD_ETHER: + case ARPHRD_LOOPBACK: + return sizeof(struct ethhdr); +#ifdef CONFIG_TR + case ARPHRD_IEEE802_TR: + return sizeof(struct trh_hdr); +#endif + } + return 0; +} + /** * llc_alloc_frame - allocates sk_buff for frame * @dev: network device this skb will be sent over + * @type: pdu type to allocate + * @data_size: data size to allocate * * Allocates an sk_buff for frame and initializes sk_buff fields. * Returns allocated skb or %NULL when out of memory. */ -struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev) +struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev, + u8 type, u32 data_size) { - struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); + int hlen = type == LLC_PDU_TYPE_U ? 3 : 4; + struct sk_buff *skb; + + hlen += llc_mac_header_len(dev->type); + skb = alloc_skb(hlen + data_size, GFP_ATOMIC); if (skb) { - skb_reserve(skb, 50); - skb->nh.raw = skb->h.raw = skb->data; + skb_reset_mac_header(skb); + skb_reserve(skb, hlen); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); skb->protocol = htons(ETH_P_802_2); skb->dev = dev; - skb->mac.raw = skb->head; if (sk != NULL) skb_set_owner_w(skb, sk); } @@ -201,7 +223,7 @@ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) if (sock_queue_rcv_skb(skb->sk, skb)) kfree_skb(skb); } - } + } kfree_skb(skb); } @@ -215,7 +237,7 @@ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) * This function is called when upper layer wants to send a TEST pdu. * Returns 0 for success, 1 otherwise. */ -void llc_build_and_send_test_pkt(struct llc_sap *sap, +void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb, u8 *dmac, u8 dsap) { struct llc_sap_state_ev *ev = llc_sap_ev(skb); @@ -224,7 +246,7 @@ void llc_build_and_send_test_pkt(struct llc_sap *sap, ev->daddr.lsap = dsap; memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN); memcpy(ev->daddr.mac, dmac, IFHWADDRLEN); - + ev->type = LLC_SAP_EV_TYPE_PRIM; ev->prim = LLC_TEST_PRIM; ev->prim_type = LLC_PRIM_TYPE_REQ; @@ -264,12 +286,14 @@ void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb, * * Sends received pdus to the sap state machine. */ -static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb) +static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb, + struct sock *sk) { struct llc_sap_state_ev *ev = llc_sap_ev(skb); ev->type = LLC_SAP_EV_TYPE_PDU; ev->reason = 0; + skb->sk = sk; llc_sap_state_process(sap, skb); } @@ -338,8 +362,7 @@ static void llc_sap_mcast(struct llc_sap *sap, break; sock_hold(sk); - skb_set_owner_r(skb1, sk); - llc_sap_rcv(sap, skb1); + llc_sap_rcv(sap, skb1, sk); sock_put(sk); } read_unlock_bh(&sap->sk_list.lock); @@ -359,8 +382,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb) } else { struct sock *sk = llc_lookup_dgram(sap, &laddr); if (sk) { - skb_set_owner_r(skb, sk); - llc_sap_rcv(sap, skb); + llc_sap_rcv(sap, skb, sk); sock_put(sk); } else kfree_skb(skb);