]> git.hungrycats.org Git - linux/commitdiff
[LLC] save sockaddr_llc info in connection packets
authorArnaldo Carvalho de Melo <acme@conectiva.com.br>
Thu, 12 Sep 2002 19:08:36 +0000 (16:08 -0300)
committerArnaldo Carvalho de Melo <acme@conectiva.com.br>
Thu, 12 Sep 2002 19:08:36 +0000 (16:08 -0300)
Also only unassign the sock from the sap if the socket
is not zapped, because autobind can fail, leaving it
unassigned...

Noticed with llcping/llcpingd from Jay, that I'm using
now to test PF_LLC SOCK_DGRAM (xid, test, ui).

Also add more debugging calls, disabled by default in
mainline.

net/llc/llc_conn.c
net/llc/llc_mac.c
net/llc/llc_sap.c
net/llc/llc_sock.c

index deda9426b4126eb16654b20fb75a0ce6f9d8b067..377887a246e4d746843e1ebf508be0267e53623b 100644 (file)
@@ -39,6 +39,24 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
 /* Offset table on connection states transition diagram */
 static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
 
+static void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
+                              u8 ua, u8 test, u8 xid)
+{
+       struct llc_opt *llc = llc_sk(sk);
+       struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
+
+       /* save primitive for use by the user. */
+       addr->sllc_family = sk->family;
+       addr->sllc_arphrd = skb->dev->type;
+       addr->sllc_test   = test;
+       addr->sllc_xid    = xid;
+       addr->sllc_ua     = ua;
+       addr->sllc_dsap   = llc->sap->laddr.lsap;
+       memcpy(addr->sllc_dmac, llc->laddr.mac, IFHWADDRLEN);
+       addr->sllc_ssap   = llc->daddr.lsap;
+       memcpy(addr->sllc_smac, llc->daddr.mac, IFHWADDRLEN);
+}
+
 /**
  *     llc_conn_state_process - sends event to connection state machine
  *     @sk: connection
@@ -56,6 +74,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
        struct llc_opt *llc = llc_sk(sk);
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
        u8 flag = ev->flag;
+       u8 status = ev->status;
        struct llc_prim_if_block *ind_prim = ev->ind_prim;
        struct llc_prim_if_block *cfm_prim = ev->cfm_prim;
 
@@ -77,6 +96,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
                 */
                switch (flag) {
                case LLC_DATA_PRIM + 1:
+                       llc_save_primitive(sk, skb, 0, 0, 0);
                        if (sock_queue_rcv_skb(sk, skb)) {
                                /*
                                 * FIXME: have to sync the LLC state
@@ -130,7 +150,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
        case LLC_CONN_PRIM + 1:
                if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT)
                        goto out_kfree_skb;
-               if (ev->status) {
+               if (status) {
                        sk->socket->state = SS_UNCONNECTED;
                        sk->state         = TCP_CLOSE;
                } else {
index 6f9250fb78f08351b6fe67000e70efe6972b950a..381ea3f58a7887767effa2bc0378c62d61f963c3 100644 (file)
@@ -102,16 +102,20 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
        fix_up_incoming_skb(skb);
        pdu = llc_pdu_sn_hdr(skb);
        if (!pdu->dsap) { /* NULL DSAP, refer to station */
+               dprintk("%s: calling llc_station_rcv!\n", __FUNCTION__);
                llc_station_rcv(skb);
                goto out;
        }
        sap = llc_sap_find(pdu->dsap);
-       if (!sap) /* unknown SAP */
+       if (!sap) {/* unknown SAP */
+               dprintk("%s: llc_sap_find(%02X) failed!\n", __FUNCTION__, pdu->dsap);
                goto drop;
+       }
        llc_decode_pdu_type(skb, &dest);
-       if (dest == LLC_DEST_SAP) /* type 1 services */
+       if (dest == LLC_DEST_SAP) { /* type 1 services */
+               dprintk("%s: calling llc_sap_rcv!\n", __FUNCTION__);
                llc_sap_rcv(sap, skb);
-       else if (dest == LLC_DEST_CONN) {
+       else if (dest == LLC_DEST_CONN) {
                struct llc_addr saddr, daddr;
                struct sock *sk;
                int rc;
index a597a2269b2ec5919ef77f2561ef68bf607c17fd..ea58322988ad7dc3033798ea87cf468b6457ec9f 100644 (file)
@@ -205,7 +205,7 @@ static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
        /* search thru events for this state until list exhausted or until
         * its obvious the event is not valid for the current state
         */
-       for (next_trans = curr_state->transitions; next_trans [i]->ev; i++)
+       for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
                if (!next_trans[i]->ev(sap, skb)) {
                        /* got event match; return it */
                        rc = next_trans[i];
index f664c4c3d5650228b4ebefe0de67de8f963df899..61ee027c4be3bce9c1550c174fd33814b030cdf9 100644 (file)
@@ -396,10 +396,11 @@ static int llc_ui_release(struct socket *sock)
                llc->laddr.lsap, llc->daddr.lsap);
        if (!llc_send_disc(sk))
                llc_ui_wait_for_disc(sk, sk->rcvtimeo);
-       llc_sap_unassign_sock(llc->sap, sk);
        release_sock(sk);
-       llc_ui_remove_socket(sk);
-
+       if (!sk->zapped) {
+               llc_sap_unassign_sock(llc->sap, sk);
+               llc_ui_remove_socket(sk);
+       }
        if (llc->sap && list_empty(&llc->sap->sk_list.list))
                llc_sap_close(llc->sap);
        sock_put(sk);
@@ -514,7 +515,8 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
                }
        }
        llc->laddr.lsap = addr->sllc_ssap;
-       memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
+       if (llc->dev)
+               memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
        llc->daddr.lsap = addr->sllc_dsap;
        memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
        memcpy(&llc->addr, addr, sizeof(llc->addr));