[LLC] save sockaddr_llc info in connection packets

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.
parent b1b28e47
...@@ -39,6 +39,24 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk, ...@@ -39,6 +39,24 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
/* Offset table on connection states transition diagram */ /* Offset table on connection states transition diagram */
static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; 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 * llc_conn_state_process - sends event to connection state machine
* @sk: connection * @sk: connection
...@@ -56,6 +74,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) ...@@ -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_opt *llc = llc_sk(sk);
struct llc_conn_state_ev *ev = llc_conn_ev(skb); struct llc_conn_state_ev *ev = llc_conn_ev(skb);
u8 flag = ev->flag; u8 flag = ev->flag;
u8 status = ev->status;
struct llc_prim_if_block *ind_prim = ev->ind_prim; struct llc_prim_if_block *ind_prim = ev->ind_prim;
struct llc_prim_if_block *cfm_prim = ev->cfm_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) ...@@ -77,6 +96,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
*/ */
switch (flag) { switch (flag) {
case LLC_DATA_PRIM + 1: case LLC_DATA_PRIM + 1:
llc_save_primitive(sk, skb, 0, 0, 0);
if (sock_queue_rcv_skb(sk, skb)) { if (sock_queue_rcv_skb(sk, skb)) {
/* /*
* FIXME: have to sync the LLC state * FIXME: have to sync the LLC state
...@@ -130,7 +150,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) ...@@ -130,7 +150,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
case LLC_CONN_PRIM + 1: case LLC_CONN_PRIM + 1:
if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT) if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT)
goto out_kfree_skb; goto out_kfree_skb;
if (ev->status) { if (status) {
sk->socket->state = SS_UNCONNECTED; sk->socket->state = SS_UNCONNECTED;
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
} else { } else {
......
...@@ -102,16 +102,20 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -102,16 +102,20 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
fix_up_incoming_skb(skb); fix_up_incoming_skb(skb);
pdu = llc_pdu_sn_hdr(skb); pdu = llc_pdu_sn_hdr(skb);
if (!pdu->dsap) { /* NULL DSAP, refer to station */ if (!pdu->dsap) { /* NULL DSAP, refer to station */
dprintk("%s: calling llc_station_rcv!\n", __FUNCTION__);
llc_station_rcv(skb); llc_station_rcv(skb);
goto out; goto out;
} }
sap = llc_sap_find(pdu->dsap); 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; goto drop;
}
llc_decode_pdu_type(skb, &dest); 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); llc_sap_rcv(sap, skb);
else if (dest == LLC_DEST_CONN) { } else if (dest == LLC_DEST_CONN) {
struct llc_addr saddr, daddr; struct llc_addr saddr, daddr;
struct sock *sk; struct sock *sk;
int rc; int rc;
......
...@@ -205,7 +205,7 @@ static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap, ...@@ -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 /* search thru events for this state until list exhausted or until
* its obvious the event is not valid for the current state * 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)) { if (!next_trans[i]->ev(sap, skb)) {
/* got event match; return it */ /* got event match; return it */
rc = next_trans[i]; rc = next_trans[i];
......
...@@ -396,10 +396,11 @@ static int llc_ui_release(struct socket *sock) ...@@ -396,10 +396,11 @@ static int llc_ui_release(struct socket *sock)
llc->laddr.lsap, llc->daddr.lsap); llc->laddr.lsap, llc->daddr.lsap);
if (!llc_send_disc(sk)) if (!llc_send_disc(sk))
llc_ui_wait_for_disc(sk, sk->rcvtimeo); llc_ui_wait_for_disc(sk, sk->rcvtimeo);
llc_sap_unassign_sock(llc->sap, sk);
release_sock(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)) if (llc->sap && list_empty(&llc->sap->sk_list.list))
llc_sap_close(llc->sap); llc_sap_close(llc->sap);
sock_put(sk); sock_put(sk);
...@@ -514,7 +515,8 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) ...@@ -514,7 +515,8 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
} }
} }
llc->laddr.lsap = addr->sllc_ssap; 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; llc->daddr.lsap = addr->sllc_dsap;
memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN); memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
memcpy(&llc->addr, addr, sizeof(llc->addr)); memcpy(&llc->addr, addr, sizeof(llc->addr));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment