[Feature][ZXW-130]merge P50U02 version
Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No
Change-Id: I4f29ec5bb7c59385f23738d2b7ca84e67c100f69
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
index 5d55426..3ad10c1 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
@@ -1116,6 +1116,29 @@
return count;
}
+static ssize_t dev_reset_set(struct file *file,
+ const char __user *buffer, size_t count, loff_t *pos)
+{
+ struct net_device *dev = NULL;
+ size_t size;
+ char dev_name[MAX_NET_DEVICE_NAME_LEN + 1] = {0};
+
+ //countβ²¿°üº¬ÁË1¸ö½áÊø·û
+ size = min(count - 1, MAX_NET_DEVICE_NAME_LEN);
+ if (copy_from_user(dev_name, buffer, size))
+ return -EFAULT;
+
+ //ɾ³ý´ËÍøÂçÉ豸Ïà¹Østat
+ dev = dev_get_by_name(&init_net, dev_name);
+ if (dev){
+ memset(&dev->stats, 0, sizeof(struct net_device_stats));
+ atomic_long_set(&dev->rx_dropped, 0);
+ dev_put(dev);
+ }else
+ printk("dev_reset_set %s not find\n", dev_name);
+ return count;
+}
+
static const struct file_operations fastnat_level_file_ops = {
.owner = THIS_MODULE,
.open = fastnat_level_open,
@@ -1196,6 +1219,11 @@
.write = skb_debug_off_set,
};
+static const struct file_operations dev_reset_file_ops = {
+ .owner = THIS_MODULE,
+ .write = dev_reset_set,
+};
+
//¿ìËÙת·¢procÎļþµÄ³õʼ»¯
int fast_conntrack_init_proc(void)
{
@@ -1225,9 +1253,12 @@
//¶ÁÈ¡Á´½Ó¶ª°üÐÅÏ¢
proc_create("pkt_lostinfo", 0440, init_net.proc_net, &pkt_lostinfo_file_ops);
-
+
//turn off skb debug
proc_create("skb_debug_off", 0440, init_net.proc_net, &skb_debug_off_file_ops);
+
+ //reset dev stats
+ proc_create("dev_reset_stats", 0440, init_net.proc_net, &dev_reset_file_ops);
return 1;
}
diff --git a/ap/os/linux/linux-3.4.x/net/socket.c b/ap/os/linux/linux-3.4.x/net/socket.c
index 7ea3abd..aa1e07f 100755
--- a/ap/os/linux/linux-3.4.x/net/socket.c
+++ b/ap/os/linux/linux-3.4.x/net/socket.c
@@ -491,6 +491,7 @@
inode->i_gid = current_fsgid();
#ifdef CONFIG_IPC_SOCKET
INIT_HLIST_HEAD(&sock->peer);
+ sock->task = current;
#endif
percpu_add(sockets_in_use, 1);
return sock;
diff --git a/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c b/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
index 867b943..a42bfc2 100755
--- a/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
+++ b/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
@@ -6,6 +6,8 @@
#include <net/af_unix.h>
#include <linux/syscalls.h>
#include <linux/file.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
//#include "ram_config.h"
#include <linux/socket_rpmsg.h>
@@ -16,6 +18,8 @@
#define sock_get_sema down_interruptible
#define sock_put_sema up
+extern int socket_rpmsg_enable;
+
struct sock_channel g_sock_chn_info;
struct sock_rpmsg g_sock_rpmsg;
struct ipc_socket *g_socket_ipc;
@@ -26,7 +30,7 @@
struct hlist_head g_ipc_sockets;
struct hlist_head g_sock_rpmsg_info;
struct hlist_head g_sockets_info;
-
+struct hlist_head g_sunaddr_info;
char* flag_value[] ={
"SOCK_DEAD",
"SOCK_DONE",
@@ -76,6 +80,9 @@
DEFINE_SPINLOCK(sock_release_peer_lock);
EXPORT_SYMBOL_GPL(sock_release_peer_lock);
+static struct dentry *ipcsocket_debugfs_dir_entry_root;
+static struct dentry *ipcsocket_debugfs_dir_entry_proc;
+
#define unix_peer(sk) (unix_sk(sk)->peer)
extern struct sock *unix_find_other_proxy(struct net *net,
@@ -96,6 +103,7 @@
extern void unix_dgram_disconnected_proxy(struct sock *sk, struct sock *other);
extern int unix_mkname_proxy(struct sockaddr_un *sunaddr, int len, unsigned *hashp);
extern void unix_release_sock_proxy(struct sock *sk);
+extern void init_peercred_proxy(struct sock *sk);
//static void delayed_release(struct work_struct *unused);
int sock_soc_socket_is_valid(struct socket* proxysock, struct socket* localsock);
@@ -103,6 +111,23 @@
static LIST_HEAD(delayed_release_list);
+#define DEFINE_SHOW_ATTRIBUTE(__name) \
+static int __name##_open(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, __name##_show, inode->i_private); \
+} \
+ \
+static const struct file_operations __name##_fops = { \
+ .owner = THIS_MODULE, \
+ .open = __name##_open, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
+
+static int ipc_socket_info_show(struct seq_file *m, void *unused);
+DEFINE_SHOW_ATTRIBUTE(ipc_socket_info);
+
enum sock_flags_cap {
SOCK_DEAD_CAP,
SOCK_DONE_CAP,
@@ -202,6 +227,32 @@
}
}
+static int ipc_socket_info_show(struct seq_file *m, void *unused)
+{
+ struct task_struct *task = NULL;
+ char taskname[TASK_COMM_LEN] = {0};
+ struct ipc_socket *p;
+ struct hlist_node *pos,*n;
+ struct socket* localsocket;
+
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_warn("sock_print_ipc_socket_info g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return 0;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ memset(taskname, 0, TASK_COMM_LEN);
+ localsocket = p->localsocket;
+ task = localsocket->task;
+ get_task_comm(taskname, task);
+ sk_soc_warn("pid=%d, taskname=%s", task->pid, taskname);
+ }
+ spin_unlock(&sock_table_lock);
+ return 0;
+}
+
static int sock_soc_is_socket_peer(struct socket* socket, struct socket* peer)
{
struct socket_info *p;
@@ -566,6 +617,68 @@
up(&psock_rpmsg_info->sock_sem);
return psock_rpmsg_info;
}
+
+bool sock_soc_ipc_sunaddr_exist(struct sockaddr_un *psockaddr_un)
+{
+ struct sock_sunaddr_info *p;
+ struct hlist_node *pos,*n;
+
+ hlist_for_each_entry_safe(p, pos, n, &g_sunaddr_info, hlist_node) {
+ if((p->sockaddr.sun_family == psockaddr_un->sun_family) \
+ &&(0 == memcmp(p->sockaddr.sun_path, psockaddr_un->sun_path, UNIX_PATH_MAX))){
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void sock_soc_insert_ipc_sunaddr(struct sockaddr_un *psockaddr_un)
+{
+ struct sock_sunaddr_info *psock_sunaddr_info = NULL;
+
+ //ÏȲ鿴sunaddrÊÇ·ñÒѾÔÚg_sunaddr_infoÖÐ
+ if(true == sock_soc_ipc_sunaddr_exist(psockaddr_un)){
+ sk_soc_info("sock_soc_insert_ipc_sunaddr, sunaddr already exist");
+ return;
+ }
+
+ psock_sunaddr_info = (struct sock_sunaddr_info *)kzalloc(sizeof(struct sock_sunaddr_info), GFP_ATOMIC);
+ if(psock_sunaddr_info == NULL){
+ sk_soc_info("sock_soc_insert_ipc_sunaddr, alloc failed");
+ return;
+ }
+ memset(psock_sunaddr_info, 0, sizeof(struct sock_sunaddr_info));
+ memcpy(&psock_sunaddr_info->sockaddr, psockaddr_un, sizeof(struct sockaddr_un));
+
+ INIT_HLIST_NODE(&psock_sunaddr_info->hlist_node);
+ hlist_add_head(&psock_sunaddr_info->hlist_node, &g_sunaddr_info);
+}
+
+static int sock_soc_del_ipc_sunaddr(struct sockaddr_un *psockaddr_un)
+{
+ struct sock_sunaddr_info *p;
+ struct hlist_node *pos,*n;
+ int ret;
+ hlist_for_each_entry_safe(p, pos, n, &g_sunaddr_info, hlist_node) {
+ if(psockaddr_un->sun_path[0]){
+ ret = strncmp(p->sockaddr.sun_path, psockaddr_un->sun_path, strlen(psockaddr_un->sun_path));
+ }else{
+ ret = strncmp(&p->sockaddr.sun_path[1], &psockaddr_un->sun_path[1], strlen(&psockaddr_un->sun_path[1]));
+ }
+
+ if((p->sockaddr.sun_family == psockaddr_un->sun_family) && (0 == ret)){
+ hlist_del(&p->hlist_node);
+ kfree(p);
+ sk_soc_info("sun_path=%s, del sucess.", psockaddr_un->sun_path);
+ return 0;
+ }
+ }
+ sk_soc_info("sun_path=%s, del failed", psockaddr_un->sun_path);
+ return -1;
+}
+
int unix_is_ipc_socket(struct sock *sock)
{
int result;
@@ -755,6 +868,18 @@
usock->rsock.remotesocket = remotesocket;
}
+//±¾µØsocket¸üк󣬸üдúÀísocketÖÐrsockÐÅÏ¢
+void usock_update(struct sock* sock, int localfd, struct socket* localsocket)
+{
+ struct unix_sock* usock;
+ if(NULL == sock){
+ return;
+ }
+ usock = unix_sk(sock);
+ usock->rsock.localfd = localfd;
+ usock->rsock.localsocket = localsocket;
+}
+
void usock_update_remote_proxy_socket(struct sock* sock, struct socket* remoteproxysocket)
{
struct unix_sock* usock;
@@ -797,6 +922,7 @@
psocket_ipc->sock->sk_fd = psocket_ipc->sockfd;
//sock_soc_set_socket_info(psocket_ipc->socket, psock_rpmsg->clientsock);
sock_hold(psocket_ipc->sock); //0704
+ init_peercred_proxy(psocket_ipc->sock);
//³õʼ»¯´úÀísocketµÄusockÐÅÏ¢
usock_init(psocket_ipc->sock, psock_rpmsg->clientfd, psock_rpmsg->clientsock, psocket_ipc->sockfd, psocket_ipc->socket, psock_rpmsg->serverfd, psock_rpmsg->serversock);
usock_update_remote_proxy_socket(psocket_ipc->sock, psock_rpmsg->serverproxysock);
@@ -1087,7 +1213,7 @@
ipcsocket->localsocket = newsock;
sk_soc_info("remotesocket=%x, localsocket=%x", ipcsocket->remotesocket, ipcsocket->localsocket);
}else{
- sk_soc_info("sock_soc_get_ipcsocket_by_proxysock failed, sock=%x", sock);
+ sk_soc_info("sock_soc_get_ipcsocket_by_proxysock failed, proxysock=%x, sock=%x", proxysock, sock);
return -1;
}
sk_soc_info("sock=%x, newsock=%x", sock, newsock);
@@ -1098,6 +1224,7 @@
sock_rpmsg.newsock = newsock;
sock_soc_del_socket_peer(sock, ipcsocket->proxysocket);
sock_soc_insert_socket_peer(newsock, ipcsocket->proxysocket);
+ usock_update(ipcsocket->sock, newsock->fd, newsock);
//newsock->peer = sock->peer; //0706
//sock->peer = NULL; //0706
sock_rpmsg.key = sock_rpmsg.serversock;
@@ -1918,14 +2045,19 @@
{
struct ipc_socket* ipc_socket;
struct socket* serverproxysock;
- ipc_socket = sock_soc_get_ipcsocket_by_proxysock(psock_rpmsg->serverproxysock);
+ serverproxysock = (struct socket*)psock_rpmsg->serverproxysock;
+ ipc_socket = sock_soc_get_ipcsocket_by_proxysock(serverproxysock->sk);
+ sk_soc_info("sock_soc_notify_proxy_change_to_server_proc serverproxysock=%x", psock_rpmsg->serverproxysock);
if(NULL != ipc_socket){
sk_soc_info("sock_soc_notify_proxy_change_to_server_proc remoteproxysocket=%x", psock_rpmsg->clientproxysock);
ipc_socket->remoteproxyfd = psock_rpmsg->clientproxyfd;
ipc_socket->remoteproxysocket = psock_rpmsg->clientproxysock;
serverproxysock = (struct socket*)psock_rpmsg->serverproxysock;
usock_update_remote_proxy_socket(serverproxysock->sk, psock_rpmsg->clientproxysock);
- }
+ }else{
+ sk_soc_info("sock_soc_notify_proxy_change_to_server_proc ipc_socket is NULL");
+ }
+
}
struct sock *sock_soc_find_other(struct socket * socket/*int fd*/,
@@ -1936,6 +2068,15 @@
struct ipc_socket *psocket_ipc = NULL;
struct sock_rpmsg_info *psock_rpmsg_info = NULL;
int err;
+
+ if(0 == socket_rpmsg_enable){
+ return NULL;
+ }
+
+ if(false == sock_soc_ipc_sunaddr_exist(sunname)){
+ sk_soc_info("sock_soc_ipc_sunaddr_exist is false, sunname=%s", sunname->sun_path);
+ return NULL;
+ }
//struct socket *clisocket = sock_get_local_socket(fd, &err);
memcpy(&sock_rpmsg.sockaddr, sunname, sizeof(struct sockaddr_un));
sock_rpmsg.addr_len = len;
@@ -1952,6 +2093,10 @@
}
psock_rpmsg_info = sock_soc_create_rpmsg_info(sock_rpmsg.key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_info("sock_soc_find_other create rpmsg faild \n");
+ return NULL;
+ }
sk_soc_info("sock_soc_find_other clientfd=%d, key=%x", sock_rpmsg.clientfd, sock_rpmsg.key);
sock_send_ipc_msg(&sock_rpmsg);
down_timeout(&psock_rpmsg_info->sock_sem, msecs_to_jiffies(g_sock_timeout));
@@ -2321,6 +2466,46 @@
return 0;
}
+void sock_soc_unix_bind(struct sockaddr_un *sunaddr)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.msg_type = MSG_TYPE_UNIX_BIND;
+
+ memcpy(&sock_rpmsg.sockaddr, sunaddr, sizeof(struct sockaddr_un));
+ sk_soc_info("sock_soc_unix_bind sunaddr=%s\n", sunaddr->sun_path);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+int sock_soc_unix_bind_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sockaddr_un sunaddr = {0};
+ memcpy(&sunaddr, &psock_rpmsg->sockaddr, sizeof(struct sockaddr_un));
+ sk_soc_info("sock_soc_unix_bind_proc sunaddr=%s\n", sunaddr.sun_path);
+ sock_soc_insert_ipc_sunaddr(&sunaddr);
+ return 0;
+}
+
+void sock_soc_unix_unbind(struct sockaddr_un *sunaddr)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.msg_type = MSG_TYPE_UNIX_UNBIND;
+
+ memcpy(&sock_rpmsg.sockaddr, sunaddr, sizeof(struct sockaddr_un));
+ sk_soc_info("sock_soc_unix_unbind sunaddr=%s\n", sunaddr->sun_path);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+int sock_soc_unix_unbind_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sockaddr_un sunaddr = {0};
+ memcpy(&sunaddr, &psock_rpmsg->sockaddr, sizeof(struct sockaddr_un));
+ sk_soc_info("sock_soc_unix_unbind_proc sunaddr=%s\n", sunaddr.sun_path);
+ sock_soc_del_ipc_sunaddr(&sunaddr);
+ return 0;
+}
+
static int sock_create_icp_channel(T_ZDrvRpMsg_ActorID core_id, T_ZDrvRpMsg_ChID channel_id, unsigned int channel_size)
{
int retval;
@@ -2438,6 +2623,12 @@
case MSG_TYPE_NOTIFY_PROXY_CHANGE:
sock_soc_notify_proxy_change_to_server_proc(sock_rpmsg);
break;
+ case MSG_TYPE_UNIX_BIND:
+ sock_soc_unix_bind_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_UNIX_UNBIND:
+ sock_soc_unix_unbind_proc(sock_rpmsg);
+ break;
default:
break;
}
@@ -2618,6 +2809,7 @@
INIT_HLIST_HEAD(&g_ipc_sockets);
INIT_HLIST_HEAD(&g_sock_rpmsg_info);
INIT_HLIST_HEAD(&g_sockets_info);
+ INIT_HLIST_HEAD(&g_sunaddr_info);
retval = sock_create_icp_channel(CAP_ID, ICP_CHN_SOCKET, ICP_CHANNEL_SIZE);
if(retval < 0) {
sk_soc_err("Create IcpChannel channel_32 fail.");
@@ -2643,7 +2835,19 @@
return PTR_ERR(th);
}
g_sock_chn_info.recv_thread_info.p_thread = th;
-
+
+ ipcsocket_debugfs_dir_entry_root = debugfs_create_dir("ipc_socket", NULL);
+ if (ipcsocket_debugfs_dir_entry_root)
+ ipcsocket_debugfs_dir_entry_proc = debugfs_create_dir("proc",
+ ipcsocket_debugfs_dir_entry_root);
+
+ if (ipcsocket_debugfs_dir_entry_root) {
+ debugfs_create_file("ipc_socket_info",
+ 0444,
+ ipcsocket_debugfs_dir_entry_root,
+ NULL,
+ &ipc_socket_info_fops);
+ }
return 0;
}
diff --git a/ap/os/linux/linux-3.4.x/net/unix/af_unix.c b/ap/os/linux/linux-3.4.x/net/unix/af_unix.c
index 013b685..30a37d0 100755
--- a/ap/os/linux/linux-3.4.x/net/unix/af_unix.c
+++ b/ap/os/linux/linux-3.4.x/net/unix/af_unix.c
@@ -119,6 +119,9 @@
#include <linux/socket_rpmsg.h>
int socket_rpmsg_debug = 0;
module_param(socket_rpmsg_debug, int, 0644);
+
+int socket_rpmsg_enable = 1;
+module_param(socket_rpmsg_enable, int, 0644);
#endif
struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
EXPORT_SYMBOL_GPL(unix_socket_table);
@@ -200,8 +203,13 @@
static inline void unix_release_addr(struct unix_address *addr)
{
- if (atomic_dec_and_test(&addr->refcnt))
+ if (atomic_dec_and_test(&addr->refcnt)){
+#ifdef CONFIG_IPC_SOCKET
+ sock_soc_unix_unbind(addr->name);
+#endif
kfree(addr);
+ }
+
}
/*
@@ -943,7 +951,9 @@
__unix_remove_socket(sk);
u->addr = addr;
__unix_insert_socket(list, sk);
-
+#ifdef CONFIG_IPC_SOCKET
+ sock_soc_unix_bind(sunaddr);
+#endif
out_unlock:
spin_unlock(&unix_table_lock);
out_up:
@@ -2617,6 +2627,10 @@
unix_release_sock(sk, 0);
}
+void init_peercred_proxy(struct sock *sk){
+ init_peercred(sk);
+}
+
#endif
static const struct net_proto_family unix_family_ops = {
diff --git a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_policy.c b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_policy.c
index 403af62..33fd9e5 100755
--- a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_policy.c
+++ b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_policy.c
@@ -813,7 +813,7 @@
walk->type != XFRM_POLICY_TYPE_ANY)
return -EINVAL;
- if (list_empty(&walk->walk.all) && walk->seq != 0)
+ if ((list_empty(&walk->walk.all) && walk->seq != 0) || walk->walk.all.next == 0)
return 0;
write_lock_bh(&xfrm_policy_lock);
@@ -858,7 +858,7 @@
void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
{
- if (list_empty(&walk->walk.all))
+ if (list_empty(&walk->walk.all) || walk->walk.all.next == 0)
return;
write_lock_bh(&xfrm_policy_lock);
diff --git a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_state.c b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_state.c
index bc512d3..8563f4e 100755
--- a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_state.c
+++ b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_state.c
@@ -1566,7 +1566,7 @@
struct xfrm_state_walk *x;
int err = 0;
- if (walk->seq != 0 && list_empty(&walk->all))
+ if ((walk->seq != 0 && list_empty(&walk->all)) || walk->all.next == 0)
return 0;
spin_lock_bh(&xfrm_state_lock);
@@ -1609,7 +1609,7 @@
void xfrm_state_walk_done(struct xfrm_state_walk *walk)
{
- if (list_empty(&walk->all))
+ if (list_empty(&walk->all) || walk->all.next == 0)
return;
spin_lock_bh(&xfrm_state_lock);
diff --git a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
index 0889855..c2d1e93 100755
--- a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
+++ b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
@@ -858,7 +858,6 @@
static int xfrm_dump_sa_done(struct netlink_callback *cb)
{
struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
- if(cb->args[1])
xfrm_state_walk_done(walk);
return 0;
}
@@ -869,8 +868,6 @@
struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
struct xfrm_dump_info info;
- if(cb->args[1] == 0)
- return 0;
BUILD_BUG_ON(sizeof(struct xfrm_state_walk) >
sizeof(cb->args) - sizeof(cb->args[0]));
@@ -1538,7 +1535,7 @@
static int xfrm_dump_policy_done(struct netlink_callback *cb)
{
struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
- if(cb->args[1])
+
xfrm_policy_walk_done(walk);
return 0;
}
@@ -1549,8 +1546,6 @@
struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
struct xfrm_dump_info info;
- if(cb->args[1] == 0)
- return 0;
BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) >
sizeof(cb->args) - sizeof(cb->args[0]));