diff options
Diffstat (limited to 'net/tipc/bcast.c')
| -rw-r--r-- | net/tipc/bcast.c | 46 | 
1 files changed, 34 insertions, 12 deletions
| diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index c5cbdcb1f0b5..a816382fc8af 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
| @@ -108,6 +108,11 @@ void tipc_bclink_remove_node(struct net *net, u32 addr) | |||
| 108 | 108 | ||
| 109 | tipc_bclink_lock(net); | 109 | tipc_bclink_lock(net); | 
| 110 | tipc_nmap_remove(&tn->bclink->bcast_nodes, addr); | 110 | tipc_nmap_remove(&tn->bclink->bcast_nodes, addr); | 
| 111 | |||
| 112 | /* Last node? => reset backlog queue */ | ||
| 113 | if (!tn->bclink->bcast_nodes.count) | ||
| 114 | tipc_link_purge_backlog(&tn->bclink->link); | ||
| 115 | |||
| 111 | tipc_bclink_unlock(net); | 116 | tipc_bclink_unlock(net); | 
| 112 | } | 117 | } | 
| 113 | 118 | ||
| @@ -115,19 +120,15 @@ static void bclink_set_last_sent(struct net *net) | |||
| 115 | { | 120 | { | 
| 116 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 121 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| 117 | struct tipc_link *bcl = tn->bcl; | 122 | struct tipc_link *bcl = tn->bcl; | 
| 118 | struct sk_buff *skb = skb_peek(&bcl->backlogq); | ||
| 119 | 123 | ||
| 120 | if (skb) | 124 | bcl->silent_intv_cnt = mod(bcl->snd_nxt - 1); | 
| 121 | bcl->fsm_msg_cnt = mod(buf_seqno(skb) - 1); | ||
| 122 | else | ||
| 123 | bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1); | ||
| 124 | } | 125 | } | 
| 125 | 126 | ||
| 126 | u32 tipc_bclink_get_last_sent(struct net *net) | 127 | u32 tipc_bclink_get_last_sent(struct net *net) | 
| 127 | { | 128 | { | 
| 128 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 129 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| 129 | 130 | ||
| 130 | return tn->bcl->fsm_msg_cnt; | 131 | return tn->bcl->silent_intv_cnt; | 
| 131 | } | 132 | } | 
| 132 | 133 | ||
| 133 | static void bclink_update_last_sent(struct tipc_node *node, u32 seqno) | 134 | static void bclink_update_last_sent(struct tipc_node *node, u32 seqno) | 
| @@ -212,16 +213,16 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) | |||
| 212 | * or both sent and unsent messages (otherwise) | 213 | * or both sent and unsent messages (otherwise) | 
| 213 | */ | 214 | */ | 
| 214 | if (tn->bclink->bcast_nodes.count) | 215 | if (tn->bclink->bcast_nodes.count) | 
| 215 | acked = tn->bcl->fsm_msg_cnt; | 216 | acked = tn->bcl->silent_intv_cnt; | 
| 216 | else | 217 | else | 
| 217 | acked = tn->bcl->next_out_no; | 218 | acked = tn->bcl->snd_nxt; | 
| 218 | } else { | 219 | } else { | 
| 219 | /* | 220 | /* | 
| 220 | * Bail out if specified sequence number does not correspond | 221 | * Bail out if specified sequence number does not correspond | 
| 221 | * to a message that has been sent and not yet acknowledged | 222 | * to a message that has been sent and not yet acknowledged | 
| 222 | */ | 223 | */ | 
| 223 | if (less(acked, buf_seqno(skb)) || | 224 | if (less(acked, buf_seqno(skb)) || | 
| 224 | less(tn->bcl->fsm_msg_cnt, acked) || | 225 | less(tn->bcl->silent_intv_cnt, acked) || | 
| 225 | less_eq(acked, n_ptr->bclink.acked)) | 226 | less_eq(acked, n_ptr->bclink.acked)) | 
| 226 | goto exit; | 227 | goto exit; | 
| 227 | } | 228 | } | 
| @@ -803,9 +804,9 @@ int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg) | |||
| 803 | goto attr_msg_full; | 804 | goto attr_msg_full; | 
| 804 | if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name)) | 805 | if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name)) | 
| 805 | goto attr_msg_full; | 806 | goto attr_msg_full; | 
| 806 | if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->next_in_no)) | 807 | if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->rcv_nxt)) | 
| 807 | goto attr_msg_full; | 808 | goto attr_msg_full; | 
| 808 | if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->next_out_no)) | 809 | if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->snd_nxt)) | 
| 809 | goto attr_msg_full; | 810 | goto attr_msg_full; | 
| 810 | 811 | ||
| 811 | prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP); | 812 | prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP); | 
| @@ -866,6 +867,27 @@ int tipc_bclink_set_queue_limits(struct net *net, u32 limit) | |||
| 866 | return 0; | 867 | return 0; | 
| 867 | } | 868 | } | 
| 868 | 869 | ||
| 870 | int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[]) | ||
| 871 | { | ||
| 872 | int err; | ||
| 873 | u32 win; | ||
| 874 | struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; | ||
| 875 | |||
| 876 | if (!attrs[TIPC_NLA_LINK_PROP]) | ||
| 877 | return -EINVAL; | ||
| 878 | |||
| 879 | err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_LINK_PROP], props); | ||
| 880 | if (err) | ||
| 881 | return err; | ||
| 882 | |||
| 883 | if (!props[TIPC_NLA_PROP_WIN]) | ||
| 884 | return -EOPNOTSUPP; | ||
| 885 | |||
| 886 | win = nla_get_u32(props[TIPC_NLA_PROP_WIN]); | ||
| 887 | |||
| 888 | return tipc_bclink_set_queue_limits(net, win); | ||
| 889 | } | ||
| 890 | |||
| 869 | int tipc_bclink_init(struct net *net) | 891 | int tipc_bclink_init(struct net *net) | 
| 870 | { | 892 | { | 
| 871 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 893 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 
| @@ -893,7 +915,7 @@ int tipc_bclink_init(struct net *net) | |||
| 893 | __skb_queue_head_init(&bcl->backlogq); | 915 | __skb_queue_head_init(&bcl->backlogq); | 
| 894 | __skb_queue_head_init(&bcl->deferdq); | 916 | __skb_queue_head_init(&bcl->deferdq); | 
| 895 | skb_queue_head_init(&bcl->wakeupq); | 917 | skb_queue_head_init(&bcl->wakeupq); | 
| 896 | bcl->next_out_no = 1; | 918 | bcl->snd_nxt = 1; | 
| 897 | spin_lock_init(&bclink->node.lock); | 919 | spin_lock_init(&bclink->node.lock); | 
| 898 | __skb_queue_head_init(&bclink->arrvq); | 920 | __skb_queue_head_init(&bclink->arrvq); | 
| 899 | skb_queue_head_init(&bclink->inputq); | 921 | skb_queue_head_init(&bclink->inputq); | 
