diff options
Diffstat (limited to 'drivers/net/ethernet/microchip/vcap/vcap_api.c')
| -rw-r--r-- | drivers/net/ethernet/microchip/vcap/vcap_api.c | 18 | 
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index 300fe1a93dce..ef980e4e5bc2 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -1021,18 +1021,32 @@ static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri,  	list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) {  		newckf = kmemdup(ckf, sizeof(*newckf), GFP_KERNEL);  		if (!newckf) -			return ERR_PTR(-ENOMEM); +			goto err;  		list_add_tail(&newckf->ctrl.list, &duprule->data.keyfields);  	}  	list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) {  		newcaf = kmemdup(caf, sizeof(*newcaf), GFP_KERNEL);  		if (!newcaf) -			return ERR_PTR(-ENOMEM); +			goto err;  		list_add_tail(&newcaf->ctrl.list, &duprule->data.actionfields);  	}  	return duprule; + +err: +	list_for_each_entry_safe(ckf, newckf, &duprule->data.keyfields, ctrl.list) { +		list_del(&ckf->ctrl.list); +		kfree(ckf); +	} + +	list_for_each_entry_safe(caf, newcaf, &duprule->data.actionfields, ctrl.list) { +		list_del(&caf->ctrl.list); +		kfree(caf); +	} + +	kfree(duprule); +	return ERR_PTR(-ENOMEM);  }  static void vcap_apply_width(u8 *dst, int width, int bytes)  |