From 1b9698e0421c493988f67564d0f4b88dfaa47ce1 Mon Sep 17 00:00:00 2001 From: Michael Blizek Date: Sun, 28 Mar 2010 18:15:47 +0200 Subject: [PATCH] add_ping_req memory corruption fix, neighbor state switching, honor states in generate_neigh_list --- net/cor/neighbor.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/net/cor/neighbor.c b/net/cor/neighbor.c index 0eb881346d3..292e830b7d6 100644 --- a/net/cor/neighbor.c +++ b/net/cor/neighbor.c @@ -221,6 +221,8 @@ __u32 generate_neigh_list(char *buf, __u32 buflen, __u32 limit, __u32 offset) char *p_totalneighs = buf; char *p_response_rows = buf + 4; + int bufferfull = 0; + __u32 total = 0; __u32 cnt = 0; @@ -237,10 +239,22 @@ __u32 generate_neigh_list(char *buf, __u32 buflen, __u32 limit, __u32 offset) struct neighbor *curr = container_of(currlh, struct neighbor, nb_list); - if (total != cnt) + __u8 state; + /* get_neigh_state not used here because it would daedlock */ + mutex_lock(&(curr->state_lock)); + state = curr->state; + mutex_unlock(&(curr->state_lock)); + + if (state != NEIGHBOR_STATE_ACTIVE) + goto cont2; + + if (total < offset) goto cont; if (unlikely(buflen - buf_offset - 6 - 2 - curr->addrlen < 0)) + bufferfull = 1; + + if (bufferfull) goto cont; put_u16(buf + buf_offset, 1, 1);/* numaddr */ @@ -262,6 +276,7 @@ __u32 generate_neigh_list(char *buf, __u32 buflen, __u32 limit, __u32 offset) cont: total++; +cont2: currlh = currlh->next; } @@ -289,6 +304,7 @@ void set_last_routdtrip(struct neighbor *nb, unsigned long time) int get_neigh_state(struct neighbor *nb) { int ret; + int switchedtostalled = 0; BUG_ON(nb == 0); @@ -298,12 +314,18 @@ int get_neigh_state(struct neighbor *nb) time_after(nb->state_time.last_roundtrip + msecs_to_jiffies(STALL_START_TIME_MS), jiffies)))) { nb->state = NEIGHBOR_STATE_STALLED; + switchedtostalled = 1; } ret = nb->state; mutex_unlock(&(nb->state_lock)); + if (switchedtostalled) { + printk(KERN_ERR "switched to stalled"); + #warning todo reset conns + } + return ret; } @@ -372,6 +394,10 @@ void ping_resp(struct neighbor *nb, __u32 cookie, __u32 respdelay) } if (nb->ping_success >= PING_SUCCESS_CNT) { + if (nb->state == NEIGHBOR_STATE_INITIAL) + printk(KERN_ERR "switched from initial to active"); + else + printk(KERN_ERR "switched from stalled to active"); nb->state = NEIGHBOR_STATE_ACTIVE; nb->ping_success = 0; nb->state_time.last_roundtrip = jiffies; @@ -388,7 +414,7 @@ out: __u32 add_ping_req(struct neighbor *nb) { struct ping_cookie *c; - int i; + __u32 i; __u32 cookie; @@ -400,7 +426,7 @@ __u32 add_ping_req(struct neighbor *nb) } get_random_bytes((char *) &i, sizeof(i)); - i = i % (PING_COOKIES_PER_NEIGH - PING_COOKIES_FIFO) + + i = (i % (PING_COOKIES_PER_NEIGH - PING_COOKIES_FIFO)) + PING_COOKIES_FIFO; found: -- 2.11.4.GIT