blob: 06751fbc6ff968212619c00e94da010914fd11df [file] [log] [blame]
/*
* glue functions, candidates to go to -core
*
* Copyright (c) 2013-2014 Andrew Yourtchenko <ayourtch@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include "nat46-glue.h"
#include "nat46-core.h"
static DEFINE_MUTEX(ref_lock);
int is_valid_nat46(nat46_instance_t *nat46) {
return (nat46 && (nat46->sig == NAT46_SIGNATURE));
}
nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair) {
nat46_instance_t *nat46 = kzalloc(sizeof(nat46_instance_t) + npairs*sizeof(nat46_xlate_rulepair_t), GFP_KERNEL);
if (!nat46) {
printk("[nat46] make_nat46_instance: can not alloc a nat46 instance with %d pairs\n", npairs);
return NULL;
} else {
printk("[nat46] make_nat46_instance: allocated nat46 instance with %d pairs\n", npairs);
}
nat46->sig = NAT46_SIGNATURE;
nat46->npairs = npairs;
nat46->refcount = 1; /* The caller gets the reference */
if (old) {
nat46->debug = old->debug;
for(; (from_ipair >= 0) && (to_ipair >= 0) &&
(from_ipair < old->npairs) && (to_ipair < nat46->npairs); from_ipair++, to_ipair++) {
nat46->pairs[to_ipair] = old->pairs[from_ipair];
}
}
return nat46;
}
nat46_instance_t *get_nat46_instance(struct sk_buff *sk) {
nat46_instance_t *nat46 = netdev_nat46_instance(sk->dev);
mutex_lock(&ref_lock);
if (is_valid_nat46(nat46)) {
nat46->refcount++;
mutex_unlock(&ref_lock);
return nat46;
} else {
mutex_unlock(&ref_lock);
printk("[nat46] get_nat46_instance: Could not find a valid NAT46 instance!");
return NULL;
}
}
void release_nat46_instance(nat46_instance_t *nat46) {
mutex_lock(&ref_lock);
nat46->refcount--;
if(0 == nat46->refcount) {
nat46->sig = FREED_NAT46_SIGNATURE;
printk("[nat46] release_nat46_instance: freeing nat46 instance with %d pairs\n", nat46->npairs);
kfree(nat46);
}
mutex_unlock(&ref_lock);
}