1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* NOTICE: This is a clean room re-implementation of libnl */ 18 19 #include <malloc.h> 20 #include "netlink-types.h" 21 #include "netlink/handlers.h" 22 23 /* Allocate a new callback handle. */ 24 struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind) 25 { 26 struct nl_cb *cb; 27 28 cb = (struct nl_cb *) malloc(sizeof(struct nl_cb)); 29 if (cb == NULL) 30 goto fail; 31 memset(cb, 0, sizeof(*cb)); 32 33 return nl_cb_get(cb); 34 fail: 35 return NULL; 36 } 37 38 /* Clone an existing callback handle */ 39 struct nl_cb *nl_cb_clone(struct nl_cb *orig) 40 { 41 struct nl_cb *new_cb; 42 int new_refcnt; 43 44 new_cb = nl_cb_alloc(NL_CB_DEFAULT); 45 if (new_cb == NULL) 46 goto fail; 47 48 /* Preserve reference count and copy original */ 49 new_refcnt = new_cb->cb_refcnt; 50 memcpy(new_cb, orig, sizeof(*orig)); 51 new_cb->cb_refcnt = new_refcnt; 52 53 return new_cb; 54 fail: 55 return NULL; 56 } 57 58 /* Set up a callback. */ 59 int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, \ 60 nl_recvmsg_msg_cb_t func, void *arg) 61 { 62 cb->cb_set[type] = func; 63 cb->cb_args[type] = arg; 64 return 0; 65 } 66 67 68 69 /* Set up an error callback. */ 70 int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, \ 71 nl_recvmsg_err_cb_t func, void *arg) 72 { 73 cb->cb_err = func; 74 cb->cb_err_arg = arg; 75 return 0; 76 77 } 78 79 struct nl_cb *nl_cb_get(struct nl_cb *cb) 80 { 81 cb->cb_refcnt++; 82 return cb; 83 } 84 85 void nl_cb_put(struct nl_cb *cb) 86 { 87 cb->cb_refcnt--; 88 if (cb->cb_refcnt <= 0) 89 free(cb); 90 91 } 92 93