[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,
/* 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 {
......
......@@ -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;
......
......@@ -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];
......
......@@ -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));
......
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