^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/atmmpc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "mpoa_caches.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "mpc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * mpoa_caches.c: Implementation of ingress and egress cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * handling functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define dprintk(format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args) /* debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define dprintk(format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) do { if (0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ddprintk(format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args) /* debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ddprintk(format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) do { if (0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static in_cache_entry *in_cache_get(__be32 dst_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) in_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) read_lock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) entry = client->in_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (entry->ctrl_info.in_dst_ip == dst_ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct mpoa_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __be32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) in_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) read_lock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) entry = client->in_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if ((entry->ctrl_info.in_dst_ip & mask) == (dst_ip & mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) in_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) read_lock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) entry = client->in_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (entry->shortcut == vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) in_cache_entry *entry = kzalloc(sizeof(in_cache_entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) pr_info("mpoa: mpoa_caches.c: new_in_cache_entry: out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) dprintk("adding an ingress entry, ip = %pI4\n", &dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) refcount_set(&entry->use, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) dprintk("new_in_cache_entry: about to lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) write_lock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) entry->next = client->in_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) entry->prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (client->in_cache != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) client->in_cache->prev = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) client->in_cache = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) entry->ctrl_info.in_dst_ip = dst_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) entry->time = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) entry->retry_time = client->parameters.mpc_p4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) entry->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) entry->entry_state = INGRESS_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) write_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) dprintk("new_in_cache_entry: unlocked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct atm_mpoa_qos *qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct k_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) entry->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (entry->entry_state == INGRESS_RESOLVED && entry->shortcut != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (entry->entry_state == INGRESS_REFRESHING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (entry->count > mpc->parameters.mpc_p1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) msg.type = SND_MPOA_RES_RQST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) msg.content.in_info = entry->ctrl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (qos != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) msg.qos = qos->qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) msg_to_mpoad(&msg, mpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) entry->reply_wait = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) entry->entry_state = INGRESS_RESOLVING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (entry->shortcut != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return CLOSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (entry->entry_state == INGRESS_RESOLVING && entry->shortcut != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (entry->count > mpc->parameters.mpc_p1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) entry->entry_state == INGRESS_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) dprintk("(%s) threshold exceeded for ip %pI4, sending MPOA res req\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) mpc->dev->name, &entry->ctrl_info.in_dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) entry->entry_state = INGRESS_RESOLVING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) msg.type = SND_MPOA_RES_RQST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) msg.content.in_info = entry->ctrl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (qos != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) msg.qos = qos->qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) msg_to_mpoad(&msg, mpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) entry->reply_wait = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return CLOSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static void in_cache_put(in_cache_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (refcount_dec_and_test(&entry->use)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) kfree_sensitive(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * This should be called with write lock on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void in_cache_remove_entry(in_cache_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct k_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) vcc = entry->shortcut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dprintk("removing an ingress entry, ip = %pI4\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) &entry->ctrl_info.in_dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (entry->prev != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) entry->prev->next = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) client->in_cache = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (entry->next != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) entry->next->prev = entry->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) client->in_ops->put(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (client->in_cache == NULL && client->eg_cache == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) msg.type = STOP_KEEP_ALIVE_SM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) msg_to_mpoad(&msg, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Check if the egress side still uses this VCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (vcc != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) eg_cache_entry *eg_entry = client->eg_ops->get_by_vcc(vcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (eg_entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) client->eg_ops->put(eg_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) vcc_release_async(vcc, -EPIPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Call this every MPC-p2 seconds... Not exactly correct solution,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) but an easy one... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static void clear_count_and_expired(struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) in_cache_entry *entry, *next_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) time64_t now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) now = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) write_lock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) entry = client->in_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) entry->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) next_entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if ((now - entry->time) > entry->ctrl_info.holding_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dprintk("holding time expired, ip = %pI4\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) &entry->ctrl_info.in_dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) client->in_ops->remove_entry(entry, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) entry = next_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) write_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Call this every MPC-p4 seconds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static void check_resolving_entries(struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct atm_mpoa_qos *qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) in_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) time64_t now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct k_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) now = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) read_lock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) entry = client->in_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (entry->entry_state == INGRESS_RESOLVING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if ((now - entry->hold_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) < client->parameters.mpc_p6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) entry = entry->next; /* Entry in hold down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if ((now - entry->reply_wait) > entry->retry_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) entry->retry_time = MPC_C1 * (entry->retry_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * Retry time maximum exceeded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * put entry in hold down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (entry->retry_time > client->parameters.mpc_p5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) entry->hold_down = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) entry->retry_time = client->parameters.mpc_p4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* Ask daemon to send a resolution request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) memset(&entry->hold_down, 0, sizeof(time64_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) msg.type = SND_MPOA_RES_RTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) memcpy(msg.MPS_ctrl, client->mps_ctrl_addr, ATM_ESA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) msg.content.in_info = entry->ctrl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (qos != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) msg.qos = qos->qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) msg_to_mpoad(&msg, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) entry->reply_wait = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Call this every MPC-p5 seconds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static void refresh_entries(struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) time64_t now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct in_cache_entry *entry = client->in_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ddprintk("refresh_entries\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) now = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) read_lock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (entry->entry_state == INGRESS_RESOLVED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (!(entry->refresh_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) entry->refresh_time = (2 * (entry->ctrl_info.holding_time))/3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if ((now - entry->reply_wait) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) entry->refresh_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dprintk("refreshing an entry.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) entry->entry_state = INGRESS_REFRESHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) read_unlock_bh(&client->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static void in_destroy_cache(struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) write_lock_irq(&mpc->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) while (mpc->in_cache != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mpc->in_ops->remove_entry(mpc->in_cache, mpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) write_unlock_irq(&mpc->ingress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static eg_cache_entry *eg_cache_get_by_cache_id(__be32 cache_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) eg_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) read_lock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) entry = mpc->eg_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (entry->ctrl_info.cache_id == cache_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) read_unlock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) read_unlock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* This can be called from any context since it saves CPU flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static eg_cache_entry *eg_cache_get_by_tag(__be32 tag, struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) eg_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) read_lock_irqsave(&mpc->egress_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) entry = mpc->eg_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (entry->ctrl_info.tag == tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) read_unlock_irqrestore(&mpc->egress_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) read_unlock_irqrestore(&mpc->egress_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* This can be called from any context since it saves CPU flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static eg_cache_entry *eg_cache_get_by_vcc(struct atm_vcc *vcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) eg_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) read_lock_irqsave(&mpc->egress_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) entry = mpc->eg_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (entry->shortcut == vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) read_unlock_irqrestore(&mpc->egress_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) read_unlock_irqrestore(&mpc->egress_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static eg_cache_entry *eg_cache_get_by_src_ip(__be32 ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) eg_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) read_lock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) entry = mpc->eg_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (entry->latest_ip_addr == ipaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) read_unlock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) read_unlock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static void eg_cache_put(eg_cache_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (refcount_dec_and_test(&entry->use)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) kfree_sensitive(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * This should be called with write lock on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static void eg_cache_remove_entry(eg_cache_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct k_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) vcc = entry->shortcut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) dprintk("removing an egress entry.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (entry->prev != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) entry->prev->next = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) client->eg_cache = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (entry->next != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) entry->next->prev = entry->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) client->eg_ops->put(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (client->in_cache == NULL && client->eg_cache == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) msg.type = STOP_KEEP_ALIVE_SM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) msg_to_mpoad(&msg, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* Check if the ingress side still uses this VCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (vcc != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) in_cache_entry *in_entry = client->in_ops->get_by_vcc(vcc, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (in_entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) client->in_ops->put(in_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) vcc_release_async(vcc, -EPIPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static eg_cache_entry *eg_cache_add_entry(struct k_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) eg_cache_entry *entry = kzalloc(sizeof(eg_cache_entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pr_info("out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) dprintk("adding an egress entry, ip = %pI4, this should be our IP\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) &msg->content.eg_info.eg_dst_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) refcount_set(&entry->use, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dprintk("new_eg_cache_entry: about to lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) write_lock_irq(&client->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) entry->next = client->eg_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) entry->prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (client->eg_cache != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) client->eg_cache->prev = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) client->eg_cache = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) entry->ctrl_info = msg->content.eg_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) entry->time = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) entry->entry_state = EGRESS_RESOLVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dprintk("new_eg_cache_entry cache_id %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ntohl(entry->ctrl_info.cache_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dprintk("mps_ip = %pI4\n", &entry->ctrl_info.mps_ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) refcount_inc(&entry->use);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) write_unlock_irq(&client->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) dprintk("new_eg_cache_entry: unlocked\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static void update_eg_cache_entry(eg_cache_entry *entry, uint16_t holding_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) entry->time = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) entry->entry_state = EGRESS_RESOLVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) entry->ctrl_info.holding_time = holding_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static void clear_expired(struct mpoa_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) eg_cache_entry *entry, *next_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) time64_t now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct k_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) now = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) write_lock_irq(&client->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) entry = client->eg_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) while (entry != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) next_entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if ((now - entry->time) > entry->ctrl_info.holding_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) msg.type = SND_EGRESS_PURGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) msg.content.eg_info = entry->ctrl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dprintk("egress_cache: holding time expired, cache_id = %u.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ntohl(entry->ctrl_info.cache_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) msg_to_mpoad(&msg, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) client->eg_ops->remove_entry(entry, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) entry = next_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) write_unlock_irq(&client->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static void eg_destroy_cache(struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) write_lock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) while (mpc->eg_cache != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) mpc->eg_ops->remove_entry(mpc->eg_cache, mpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) write_unlock_irq(&mpc->egress_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static const struct in_cache_ops ingress_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .add_entry = in_cache_add_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .get = in_cache_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .get_with_mask = in_cache_get_with_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .get_by_vcc = in_cache_get_by_vcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .put = in_cache_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .remove_entry = in_cache_remove_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .cache_hit = cache_hit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .clear_count = clear_count_and_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .check_resolving = check_resolving_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .refresh = refresh_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .destroy_cache = in_destroy_cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static const struct eg_cache_ops egress_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .add_entry = eg_cache_add_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .get_by_cache_id = eg_cache_get_by_cache_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .get_by_tag = eg_cache_get_by_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .get_by_vcc = eg_cache_get_by_vcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .get_by_src_ip = eg_cache_get_by_src_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .put = eg_cache_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .remove_entry = eg_cache_remove_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .update = update_eg_cache_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .clear_expired = clear_expired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .destroy_cache = eg_destroy_cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) void atm_mpoa_init_cache(struct mpoa_client *mpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) mpc->in_ops = &ingress_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) mpc->eg_ops = &egress_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }