Commit ae7eb260 authored by David S. Miller's avatar David S. Miller

Merge master.kernel.org:/home/acme/BK/llc-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 126672f8 86b74abd
......@@ -216,4 +216,6 @@ extern void llc_conn_busy_tmr_cb(unsigned long timeout_data);
extern void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data);
extern void llc_conn_ack_tmr_cb(unsigned long timeout_data);
extern void llc_conn_rej_tmr_cb(unsigned long timeout_data);
extern void llc_conn_set_p_flag(struct sock *sk, u8 value);
#endif /* LLC_C_AC_H */
......@@ -50,6 +50,18 @@
struct udp_mib udp_stats_in6[NR_CPUS*2];
static __inline__ int udv6_rcv_saddr_equal(struct sock *sk, struct sock *sk2)
{
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
return !inet_sk(sk2)->rcv_saddr || addr_type == IPV6_ADDR_ANY ||
(sk2->family == AF_INET6 &&
!ipv6_addr_cmp(&np->rcv_saddr, &inet6_sk(sk2)->rcv_saddr)) ||
(addr_type == IPV6_ADDR_MAPPED && sk2->family == AF_INET &&
inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr);
}
/* Grrr, addr_type already calculated by caller, but I don't want
* to add some silly "cookie" argument to this method just for that.
*/
......@@ -98,25 +110,15 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum)
udp_port_rover = snum = result;
} else {
struct sock *sk2;
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
sk2 != NULL;
sk2 = sk2->next) {
struct inet_opt *inet2 = inet_sk(sk2);
struct ipv6_pinfo *np2 = inet6_sk(sk2);
if (inet2->num == snum &&
if (inet_sk(sk2)->num == snum &&
sk2 != sk &&
sk2->bound_dev_if == sk->bound_dev_if &&
(!inet2->rcv_saddr ||
addr_type == IPV6_ADDR_ANY ||
!ipv6_addr_cmp(&np->rcv_saddr, &np2->rcv_saddr) ||
(addr_type == IPV6_ADDR_MAPPED &&
sk2->family == AF_INET &&
inet_sk(sk)->rcv_saddr == inet2->rcv_saddr)) &&
(!sk2->reuse || !sk->reuse))
(!sk2->reuse || !sk->reuse) &&
udv6_rcv_saddr_equal(sk, sk2))
goto fail;
}
}
......
......@@ -813,6 +813,16 @@ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
return rc;
}
void llc_conn_set_p_flag(struct sock *sk, u8 value)
{
int state_changed = llc_sk(sk)->p_flag && !value;
llc_sk(sk)->p_flag = value;
if (state_changed)
sk->state_change(sk);
}
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
......@@ -834,7 +844,8 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
rc = 0;
llc_conn_send_pdu(sk, nskb);
}
llc->p_flag = p_bit;
llc_conn_set_p_flag(sk, p_bit);
return rc;
}
......@@ -897,7 +908,7 @@ int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
llc->p_flag = 1;
llc_conn_set_p_flag(sk, 1);
mod_timer(&llc->pf_cycle_timer.timer,
jiffies + llc->pf_cycle_timer.expire * HZ);
return 0;
......@@ -1205,7 +1216,7 @@ int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb)
struct llc_opt *llc = llc_sk(sk);
del_timer(&llc->pf_cycle_timer.timer);
llc->p_flag = 0;
llc_conn_set_p_flag(sk, 0);
return 0;
}
......@@ -1259,7 +1270,7 @@ int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb)
llc_pdu_decode_pf_bit(skb, &f_bit);
if (f_bit) {
llc_sk(sk)->p_flag = 0;
llc_conn_set_p_flag(sk, 0);
llc_conn_ac_stop_p_timer(sk, skb);
}
}
......@@ -1294,13 +1305,13 @@ int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->p_flag = 0;
llc_conn_set_p_flag(sk, 0);
return 0;
}
int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->p_flag = 1;
llc_conn_set_p_flag(sk, 1);
return 0;
}
......
......@@ -39,22 +39,20 @@ 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)
void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
{
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);
addr->sllc_test = prim == LLC_TEST_PRIM;
addr->sllc_xid = prim == LLC_XID_PRIM;
addr->sllc_ua = prim == LLC_DATAUNIT_PRIM;
llc_pdu_decode_sa(skb, addr->sllc_smac);
llc_pdu_decode_da(skb, addr->sllc_dmac);
llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
}
/**
......@@ -96,7 +94,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);
llc_save_primitive(sk, skb, LLC_DATA_PRIM);
if (sock_queue_rcv_skb(sk, skb)) {
/*
* FIXME: have to sync the LLC state
......@@ -378,16 +376,20 @@ void llc_conn_free_ev(struct sk_buff *skb)
static int llc_conn_service(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct llc_opt *llc = llc_sk(sk);
struct llc_conn_state_trans *trans;
if (llc_sk(sk)->state > NBR_CONN_STATES)
if (llc->state > NBR_CONN_STATES)
goto out;
rc = 0;
trans = llc_qualify_conn_ev(sk, skb);
if (trans) {
rc = llc_exec_conn_trans_actions(sk, trans, skb);
if (!rc && trans->next_state != NO_STATE_CHANGE)
llc_sk(sk)->state = trans->next_state;
if (!rc && trans->next_state != NO_STATE_CHANGE) {
llc->state = trans->next_state;
if (!llc_data_accept_state(llc->state))
sk->state_change(sk);
}
}
out:
return rc;
......
......@@ -304,7 +304,7 @@ void llc_sk_reset(struct sock *sk)
llc->remote_busy_flag = 0;
llc->cause_flag = 0;
llc->retry_count = 0;
llc->p_flag = 0;
llc_conn_set_p_flag(sk, 0);
llc->f_flag = 0;
llc->s_flag = 0;
llc->ack_pf = 0;
......
......@@ -1320,18 +1320,26 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
{
off_t pos = 0;
off_t begin = 0;
struct sock *s;
struct llc_opt *llc;
struct llc_sap *sap;
struct list_head *sap_entry, *llc_entry;
struct llc_station *station = llc_station_get();
int len = sprintf(buffer, "SKt Mc local_mac_sap "
"remote_mac_sap tx_queue rx_queue st uid "
"link\n");
/* Output the LLC socket data for the /proc filesystem */
read_lock_bh(&llc_ui_sockets_lock);
for (s = llc_ui_sockets; s; s = s->next) {
struct llc_opt *llc = llc_sk(s);
spin_lock_bh(&station->sap_list.lock);
list_for_each(sap_entry, &station->sap_list.list) {
sap = list_entry(sap_entry, struct llc_sap, node);
spin_lock_bh(&sap->sk_list.lock);
list_for_each(llc_entry, &sap->sk_list.list) {
llc = list_entry(llc_entry, struct llc_opt, node);
len += sprintf(buffer + len, "%2X %2X ", s->type,
!llc_mac_null(llc->addr.sllc_mmac));
if (llc->sap) {
len += sprintf(buffer + len, "%2X %2X ",
llc->sk->type,
!llc_mac_null(llc->addr.sllc_mmac));
if (llc->dev && llc_mac_null(llc->addr.sllc_mmac))
llc_ui_format_mac(buffer + len,
llc->dev->dev_addr);
......@@ -1344,30 +1352,32 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
"00:00:00:00:00:00");
}
len += MAC_FORMATTED_SIZE;
len += sprintf(buffer + len, "@%02X ",
llc->sap->laddr.lsap);
} else
len += sprintf(buffer + len, "00:00:00:00:00:00@00 ");
llc_ui_format_mac(buffer + len, llc->addr.sllc_dmac);
len += MAC_FORMATTED_SIZE;
len += sprintf(buffer + len,
"@%02X %8d %8d %2d %-3d ",
llc->addr.sllc_dsap,
atomic_read(&s->wmem_alloc),
atomic_read(&s->rmem_alloc), s->state,
SOCK_INODE(s->socket)->i_uid);
len += sprintf(buffer + len, "%-4d\n", llc->link);
/* Are we still dumping unwanted data then discard the record */
pos = begin + len;
if (pos < offset) {
len = 0; /* Keep dumping into the buffer start */
begin = pos;
len += sprintf(buffer + len, "@%02X ", sap->laddr.lsap);
llc_ui_format_mac(buffer + len, llc->addr.sllc_dmac);
len += MAC_FORMATTED_SIZE;
len += sprintf(buffer + len,
"@%02X %8d %8d %2d %3d ",
llc->addr.sllc_dsap,
atomic_read(&llc->sk->wmem_alloc),
atomic_read(&llc->sk->rmem_alloc),
llc->sk->state,
llc->sk->socket ?
SOCK_INODE(llc->sk->socket)->i_uid :
-1);
len += sprintf(buffer + len, "%4d\n", llc->link);
/* Are we still dumping unwanted data then discard the record */
pos = begin + len;
if (pos < offset) {
len = 0; /* Keep dumping into the buffer start */
begin = pos;
}
if (pos > offset + length) /* We have dumped enough */
break;
}
if (pos > offset + length) /* We have dumped enough */
break;
spin_unlock_bh(&sap->sk_list.lock);
}
read_unlock_bh(&llc_ui_sockets_lock);
spin_unlock_bh(&station->sap_list.lock);
/* The data in question runs from begin to begin + len */
*start = buffer + offset - begin; /* Start of wanted data */
......
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