mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-03 12:34:19 +00:00
realtek: fix memory leak in netevent handler
The net_event_work struct is allocated, but only freed in a single case.
Move the allocation to the branch where it is actually needed, and free
it after the work has been done.
Fixes: 03e1d93e07
("realtek: add driver support for routing offload")
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
This commit is contained in:
parent
1352e5da8d
commit
65b2bcbf5f
@ -1286,6 +1286,8 @@ static void rtl83xx_net_event_work_do(struct work_struct *work)
|
|||||||
struct rtl838x_switch_priv *priv = net_work->priv;
|
struct rtl838x_switch_priv *priv = net_work->priv;
|
||||||
|
|
||||||
rtl83xx_l3_nexthop_update(priv, net_work->gw_addr, net_work->mac);
|
rtl83xx_l3_nexthop_update(priv, net_work->gw_addr, net_work->mac);
|
||||||
|
|
||||||
|
kfree(net_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl83xx_netevent_event(struct notifier_block *this,
|
static int rtl83xx_netevent_event(struct notifier_block *this,
|
||||||
@ -1299,13 +1301,6 @@ static int rtl83xx_netevent_event(struct notifier_block *this,
|
|||||||
|
|
||||||
priv = container_of(this, struct rtl838x_switch_priv, ne_nb);
|
priv = container_of(this, struct rtl838x_switch_priv, ne_nb);
|
||||||
|
|
||||||
net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
|
|
||||||
if (!net_work)
|
|
||||||
return NOTIFY_BAD;
|
|
||||||
|
|
||||||
INIT_WORK(&net_work->work, rtl83xx_net_event_work_do);
|
|
||||||
net_work->priv = priv;
|
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NETEVENT_NEIGH_UPDATE:
|
case NETEVENT_NEIGH_UPDATE:
|
||||||
if (n->tbl != &arp_tbl)
|
if (n->tbl != &arp_tbl)
|
||||||
@ -1314,10 +1309,16 @@ static int rtl83xx_netevent_event(struct notifier_block *this,
|
|||||||
port = rtl83xx_port_dev_lower_find(dev, priv);
|
port = rtl83xx_port_dev_lower_find(dev, priv);
|
||||||
if (port < 0 || !(n->nud_state & NUD_VALID)) {
|
if (port < 0 || !(n->nud_state & NUD_VALID)) {
|
||||||
pr_debug("%s: Neigbour invalid, not updating\n", __func__);
|
pr_debug("%s: Neigbour invalid, not updating\n", __func__);
|
||||||
kfree(net_work);
|
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
|
||||||
|
if (!net_work)
|
||||||
|
return NOTIFY_BAD;
|
||||||
|
|
||||||
|
INIT_WORK(&net_work->work, rtl83xx_net_event_work_do);
|
||||||
|
net_work->priv = priv;
|
||||||
|
|
||||||
net_work->mac = ether_addr_to_u64(n->ha);
|
net_work->mac = ether_addr_to_u64(n->ha);
|
||||||
net_work->gw_addr = *(__be32 *) n->primary_key;
|
net_work->gw_addr = *(__be32 *) n->primary_key;
|
||||||
|
|
||||||
|
@ -1282,6 +1282,8 @@ static void rtl83xx_net_event_work_do(struct work_struct *work)
|
|||||||
struct rtl838x_switch_priv *priv = net_work->priv;
|
struct rtl838x_switch_priv *priv = net_work->priv;
|
||||||
|
|
||||||
rtl83xx_l3_nexthop_update(priv, net_work->gw_addr, net_work->mac);
|
rtl83xx_l3_nexthop_update(priv, net_work->gw_addr, net_work->mac);
|
||||||
|
|
||||||
|
kfree(net_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl83xx_netevent_event(struct notifier_block *this,
|
static int rtl83xx_netevent_event(struct notifier_block *this,
|
||||||
@ -1295,13 +1297,6 @@ static int rtl83xx_netevent_event(struct notifier_block *this,
|
|||||||
|
|
||||||
priv = container_of(this, struct rtl838x_switch_priv, ne_nb);
|
priv = container_of(this, struct rtl838x_switch_priv, ne_nb);
|
||||||
|
|
||||||
net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
|
|
||||||
if (!net_work)
|
|
||||||
return NOTIFY_BAD;
|
|
||||||
|
|
||||||
INIT_WORK(&net_work->work, rtl83xx_net_event_work_do);
|
|
||||||
net_work->priv = priv;
|
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NETEVENT_NEIGH_UPDATE:
|
case NETEVENT_NEIGH_UPDATE:
|
||||||
if (n->tbl != &arp_tbl)
|
if (n->tbl != &arp_tbl)
|
||||||
@ -1310,10 +1305,16 @@ static int rtl83xx_netevent_event(struct notifier_block *this,
|
|||||||
port = rtl83xx_port_dev_lower_find(dev, priv);
|
port = rtl83xx_port_dev_lower_find(dev, priv);
|
||||||
if (port < 0 || !(n->nud_state & NUD_VALID)) {
|
if (port < 0 || !(n->nud_state & NUD_VALID)) {
|
||||||
pr_debug("%s: Neigbour invalid, not updating\n", __func__);
|
pr_debug("%s: Neigbour invalid, not updating\n", __func__);
|
||||||
kfree(net_work);
|
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
|
||||||
|
if (!net_work)
|
||||||
|
return NOTIFY_BAD;
|
||||||
|
|
||||||
|
INIT_WORK(&net_work->work, rtl83xx_net_event_work_do);
|
||||||
|
net_work->priv = priv;
|
||||||
|
|
||||||
net_work->mac = ether_addr_to_u64(n->ha);
|
net_work->mac = ether_addr_to_u64(n->ha);
|
||||||
net_work->gw_addr = *(__be32 *) n->primary_key;
|
net_work->gw_addr = *(__be32 *) n->primary_key;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user