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