#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
#include <linux/netfilter_ipv4/ip_conntrack_esp.h>
-#define ESP_TIMEOUT (30*HZ)
-#define ESP_STREAM_TIMEOUT (180*HZ)
+#define ESP_REF_TMOUT (30 * HZ)
+#define ESP_CONN_TMOUT (60 * HZ * 6)
+#define ESP_TMOUT_COUNT (ESP_CONN_TMOUT/ESP_REF_TMOUT)
#ifdef CONFIG_MIPS_BRCM
#define ESP_UNREPLIEDDNS_TIMEOUT (1*HZ)
u_int32_t r_ip;
u_int32_t timeout;
u_int16_t tspi;
+ struct ip_conntrack *ct;
+ struct timer_list refresh_timer;
+ int timer_active;
+ int pkt_rcvd;
+ int ntimeouts;
int inuse;
};
static u_int16_t cur_spi = 0;
+static void
+esp_free_entry(int index)
+{
+ if (esp_table[index].inuse) {
+ if (esp_table[index].timer_active) {
+#if IP_CONNTRACK_ESP_DEBUG
+ printk (KERN_DEBUG "%s:%s Deleting timer index %d\n",
+ __FILE__, __FUNCTION__, index);
+#endif
+ del_timer(&esp_table[index].refresh_timer);
+ }
+ memset(&esp_table[index], 0, sizeof(struct _esp_table));
+ }
+}
+
+static void
+esp_refresh_ct(unsigned long data)
+{
+ struct _esp_table *esp_entry = NULL;
+
+ if (data > MAX_PORTS) {
+ return;
+ }
+
+ esp_entry = &esp_table[data];
+ if ( esp_entry == NULL ) {
+ return;
+ }
+#if IP_CONNTRACK_ESP_DEBUG
+ printk(KERN_DEBUG "ntimeouts %d pkt_rcvd %d entry %p data %lu ct %p\n",
+ esp_entry->ntimeouts, esp_entry->pkt_rcvd, esp_entry, data,
+ esp_entry->ct);
+#endif
+ if (esp_entry->pkt_rcvd) {
+ esp_entry->pkt_rcvd = 0;
+ esp_entry->ntimeouts = 0;
+ } else {
+ esp_entry->ntimeouts++;
+ if (esp_entry->ntimeouts >= ESP_TMOUT_COUNT) {
+ esp_free_entry(data);
+ return;
+ }
+ }
+ esp_entry->refresh_timer.expires = jiffies + ESP_REF_TMOUT;
+ esp_entry->refresh_timer.function = esp_refresh_ct;
+ esp_entry->refresh_timer.data = data;
+ ip_ct_refresh(esp_entry->ct, ESP_CONN_TMOUT);
+ add_timer(&esp_entry->refresh_timer);
+ esp_entry->timer_active = 1;
+#if IP_CONNTRACK_ESP_DEBUG
+ printk(KERN_DEBUG "%s:%s Refreshed timer pkt_rcvd %d timeouts %d\n",
+ __FILE__, __FUNCTION__, esp_entry->pkt_rcvd, esp_entry->ntimeouts);
+#endif
+}
+
/*
* Allocate a free IPSEC table entry.
*/
if ( esp_entry->inuse == IPSEC_FREE ) {
esp_entry->tspi = cur_spi = TEMP_SPI_START + idx;
esp_entry->inuse = IPSEC_INUSE;
- //printk ( KERN_DEBUG "%s:%s New esp_entry at idx %d entry %p"
- // " tspi %u cspi %u\n", __FILE__, __FUNCTION__, idx,
- // esp_entry, esp_entry->tspi, cur_spi );
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s New esp_entry at idx %d entry %p"
+ " tspi %u cspi %u\n", __FILE__, __FUNCTION__, idx,
+ esp_entry, esp_entry->tspi, cur_spi );
+#endif
+ init_timer(&esp_entry->refresh_timer);
+ esp_entry->refresh_timer.data = idx;
+ esp_entry->pkt_rcvd = 0;
+ esp_entry->refresh_timer.expires = jiffies + ESP_REF_TMOUT;
+ esp_entry->refresh_timer.function = esp_refresh_ct;
+ add_timer(&esp_entry->refresh_timer);
+ esp_entry->timer_active = 1;
return esp_entry;
}
esp_entry++;
int idx = 0;
struct _esp_table *esp_entry = esp_table;
- //printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u\n", __FILE__, __FUNCTION__,
- // ntohl(esph->spi), NIPQUAD(daddr));
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u\n", __FILE__, __FUNCTION__,
+ ntohl(esph->spi), NIPQUAD(daddr));
+#endif
for ( ; idx < MAX_PORTS; idx++, esp_entry++ ) {
if ( esp_entry->inuse == IPSEC_FREE ) {
continue;
if ( esp_entry->l_spi != 0 && esp_entry->r_spi != 0 ) {
if ( esp_entry->l_spi == ntohl(esph->spi) ||
esp_entry->r_spi == ntohl(esph->spi) ) {
+#if IP_CONNTRACK_ESP_DEBUG
+ printk (KERN_DEBUG "%s:%s Both Ways Traffic Entry %p\n",
+ __FILE__, __FUNCTION__, esp_entry);
+#endif
return esp_entry;
}
continue;
/* We have traffic from local */
if ( esp_entry->l_spi ) {
if ( ntohl(esph->spi) == esp_entry->l_spi ) {
+#if IP_CONNTRACK_ESP_DEBUG
+ printk (KERN_DEBUG "%s:%s One Way Traffic From Local Entry %p\n",
+ __FILE__, __FUNCTION__, esp_entry);
+#endif
return esp_entry;
}
/* This must be the first packet from remote */
esp_entry->r_spi = ntohl(esph->spi);
esp_entry->r_ip = ntohl(daddr);
+#if IP_CONNTRACK_ESP_DEBUG
+ printk (KERN_DEBUG "%s:%s First Packet from Remote Entry %p\n",
+ __FILE__, __FUNCTION__, esp_entry);
+#endif
return esp_entry;
/* We have seen traffic only from remote */
} else if ( esp_entry->r_spi ) {
if ( ntohl(esph->spi) == esp_entry->r_spi ) {
+#if IP_CONNTRACK_ESP_DEBUG
+ printk (KERN_DEBUG "%s:%s One Way Traffic From Remote Entry %p\n",
+ __FILE__, __FUNCTION__, esp_entry);
+#endif
return esp_entry;
}
/* This must be the first packet from local */
esp_entry->l_spi = ntohl(esph->spi);
+#if IP_CONNTRACK_ESP_DEBUG
+ printk (KERN_DEBUG "%s:%s First Packet From Remote Entry %p\n",
+ __FILE__, __FUNCTION__, esp_entry);
+#endif
return esp_entry;
}
}
}
+#if IP_CONNTRACK_ESP_DEBUG
+ printk (KERN_DEBUG "%s:%s No Entry\n", __FILE__, __FUNCTION__);
+#endif
return NULL;
}
{
struct esphdr esph;
struct _esp_table *esp_entry;
+ const struct iphdr *iph = skb->nh.iph;
if (skb_copy_bits(skb, dataoff, &esph, sizeof(esph)) != 0)
return 0;
- //printk ( KERN_DEBUG "%s:%s (0x%x) IP Pkt Hdr %u.%u.%u.%u <-> %u.%u.%u.%u\n",
- // __FILE__, __FUNCTION__, ntohl(esph.spi),
- // NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
- //printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u\n",
- // __FILE__, __FUNCTION__, ntohl(esph.spi),
- // NIPQUAD(tuple->src.ip), NIPQUAD(tuple->dst.ip) );
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s (0x%x) IP Pkt Hdr %u.%u.%u.%u <-> %u.%u.%u.%u\n",
+ __FILE__, __FUNCTION__, ntohl(esph.spi),
+ NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+ printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u\n",
+ __FILE__, __FUNCTION__, ntohl(esph.spi),
+ NIPQUAD(tuple->src.ip), NIPQUAD(tuple->dst.ip) );
+#endif
if ( (esp_entry = search_esp_entry_by_spi ( &esph, tuple->dst.ip ) ) == NULL ) {
esp_entry = alloc_esp_entry();
esp_entry->l_spi = ntohl(esph.spi);
esp_entry->l_ip = ntohl(tuple->src.ip);
}
- //printk ( KERN_DEBUG "%s:%s tspi %u cspi %u spi 0x%x seq 0x%x"
- // " sip %u.%u.%u.%u dip %u.%u.%u.%u\n", __FILE__,
- // __FUNCTION__, esp_entry->tspi, cur_spi,
- // ntohl(esph.spi), ntohl(esph.seq),
- // NIPQUAD(tuple->src.ip), NIPQUAD(tuple->dst.ip) );
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s tspi %u cspi %u spi 0x%x seq 0x%x"
+ " sip %u.%u.%u.%u dip %u.%u.%u.%u\n", __FILE__,
+ __FUNCTION__, esp_entry->tspi, cur_spi,
+ ntohl(esph.spi), ntohl(esph.seq),
+ NIPQUAD(tuple->src.ip), NIPQUAD(tuple->dst.ip) );
+#endif
tuple->dst.u.esp.spi = esp_entry->tspi;
tuple->src.u.esp.spi = esp_entry->tspi;
+ esp_entry->pkt_rcvd++;
return 1;
}
static int esp_invert_tuple(struct ip_conntrack_tuple *tuple,
const struct ip_conntrack_tuple *orig)
{
- //printk ( KERN_DEBUG "%s:%s cspi 0x%x dspi 0x%x sspi 0x%x"
- // " %u.%u.%u.%u <-> %u.%u.%u.%u\n",
- // __FILE__, __FUNCTION__, cur_spi, orig->dst.u.esp.spi,
- // orig->src.u.esp.spi, NIPQUAD(tuple->src.ip),
- // NIPQUAD(tuple->dst.ip) );
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s cspi 0x%x dspi 0x%x sspi 0x%x"
+ " %u.%u.%u.%u <-> %u.%u.%u.%u\n",
+ __FILE__, __FUNCTION__, cur_spi, orig->dst.u.esp.spi,
+ orig->src.u.esp.spi, NIPQUAD(tuple->src.ip),
+ NIPQUAD(tuple->dst.ip) );
+#endif
tuple->src.u.esp.spi = orig->dst.u.esp.spi;
tuple->dst.u.esp.spi = orig->src.u.esp.spi;
return 1;
const struct esphdr *esph = (void *)iph + iph->ihl*4;
struct _esp_table *esp_entry;
- //printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u %s\n",
- // __FILE__, __FUNCTION__, ntohl(esph->spi),
- // NIPQUAD(iph->saddr), NIPQUAD(iph->daddr),
- // (conntrackinfo == IP_CT_NEW ) ? "CT_NEW" : "SEEN_REPLY" );
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u %s\n",
+ __FILE__, __FUNCTION__, ntohl(esph->spi),
+ NIPQUAD(iph->saddr), NIPQUAD(iph->daddr),
+ (conntrackinfo == IP_CT_NEW ) ? "CT_NEW" : "SEEN_REPLY" );
+#endif
/*
* This should not happen. We get into this routine only if there is
* an existing stream.
*/
+#if IP_CONNTRACK_ESP_DEBUG
+ printk(KERN_DEBUG "%s:%s conntrackinfo %d\n", __FILE__, __FUNCTION__, conntrackinfo);
+#endif
if (conntrackinfo == IP_CT_NEW ) {
- //printk ( KERN_DEBUG "%s:%s IP_CT_NEW (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u\n",
- // __FILE__, __FUNCTION__, esph->spi, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s IP_CT_NEW (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u\n",
+ __FILE__, __FUNCTION__, esph->spi, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+#endif
if ( (esp_entry = search_esp_entry_by_spi ( esph,
iph->daddr ) ) == NULL ) {
esp_entry = alloc_esp_entry ();
if ( esp_entry == NULL ) {
/* All entries are currently in use */
- //printk ( KERN_DEBUG "%s:%s All connections in use\n",
- // __FILE__, __FUNCTION__);
+ printk ( KERN_DEBUG "%s:%s All connections in use\n",
+ __FILE__, __FUNCTION__);
return NF_DROP;
}
esp_entry->l_spi = ntohl(esph->spi);
esp_entry->l_ip = ntohl(iph->saddr);
esp_entry->r_spi = 0;
}
+ esp_entry->pkt_rcvd++;
+#if IP_CONNTRACK_ESP_DEBUG
+ printk( KERN_DEBUG "%s:%s Received COUNT %d\n", __FILE__, __FUNCTION__, esp_entry->pkt_rcvd);
+#endif
}
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
+#if IP_CONNTRACK_ESP_DEBUG
+ printk(KERN_DEBUG "%s:%s status %lu\n", __FILE__, __FUNCTION__, conntrack->status);
+#endif
if (conntrack->status & IPS_SEEN_REPLY) {
- ip_ct_refresh(conntrack, ESP_STREAM_TIMEOUT);
+ ip_ct_refresh(conntrack, ESP_CONN_TMOUT);
/* Also, more likely to be important, and not a probe */
set_bit(IPS_ASSURED_BIT, &conntrack->status);
} else {
- ip_ct_refresh(conntrack, ESP_TIMEOUT);
+ ip_ct_refresh(conntrack, ESP_REF_TMOUT);
}
//esp_entry = search_esp_entry_by_spi ( esph, iph->daddr );
- if ( esp_entry != NULL ) {
- //printk ( KERN_DEBUG "%s:%s can modify this %u.%u.%u.%u"
- // " with %u.%u.%u.%u\n",
- // __FILE__, __FUNCTION__,
- // NIPQUAD(conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip),
- // NIPQUAD(esp_entry->l_ip) );
- }
return NF_ACCEPT;
}
const struct iphdr *iph = skb->nh.iph;
const struct esphdr *esph = (void *)iph + iph->ihl*4;
struct _esp_table *esp_entry;
- //printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u\n",
- // __FILE__, __FUNCTION__, ntohl(esph->spi),
- // NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+#if IP_CONNTRACK_ESP_DEBUG
+ printk ( KERN_DEBUG "%s:%s (0x%x) %u.%u.%u.%u <-> %u.%u.%u.%u\n",
+ __FILE__, __FUNCTION__, ntohl(esph->spi),
+ NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+#endif
if ( (esp_entry = search_esp_entry_by_spi ( esph, iph->daddr ) ) == NULL ) {
/*
* Check if this is the same LAN client creating another session.
esp_entry = alloc_esp_entry ();
if ( esp_entry == NULL ) {
/* All entries are currently in use */
- //printk ( KERN_DEBUG "%s:%s All connections in use\n",
- // __FILE__, __FUNCTION__);
+ printk ( KERN_DEBUG "%s:%s All connections in use\n",
+ __FILE__, __FUNCTION__);
return NF_DROP;
}
esp_entry->l_spi = ntohl(esph->spi);
esp_entry->l_ip = ntohl(iph->saddr);
esp_entry->r_spi = 0;
}
+ esp_entry->pkt_rcvd++;
+ esp_entry->ct = conntrack;
return 1;
}